// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:front_end/src/fasta/fasta_codes.dart';
import 'package:front_end/src/fasta/parser/parser.dart';
import 'package:front_end/src/scanner/token.dart';

class DirectiveContext {
  DirectiveState state = DirectiveState.Unknown;

  void checkScriptTag(Parser parser, Token token) {
    if (state == DirectiveState.Unknown) {
      state = DirectiveState.Script;
      return;
    }
    // The scanner only produces the SCRIPT_TAG
    // when it is the first token in the file.
    throw "Internal error: Unexpected script tag.";
  }

  void checkDeclaration() {
    if (state != DirectiveState.PartOf) {
      state = DirectiveState.Declarations;
    }
  }

  void checkExport(Parser parser, Token token) {
    if (state.index <= DirectiveState.ImportAndExport.index) {
      state = DirectiveState.ImportAndExport;
      return;
    }
    // Recovery
    if (state == DirectiveState.Part) {
      parser.reportRecoverableError(token, messageExportAfterPart);
    } else if (state == DirectiveState.PartOf) {
      parser.reportRecoverableError(token, messageNonPartOfDirectiveInPart);
    } else {
      parser.reportRecoverableError(token, messageDirectiveAfterDeclaration);
    }
  }

  void checkImport(Parser parser, Token token) {
    if (state.index <= DirectiveState.ImportAndExport.index) {
      state = DirectiveState.ImportAndExport;
      return;
    }
    // Recovery
    if (state == DirectiveState.Part) {
      parser.reportRecoverableError(token, messageImportAfterPart);
    } else if (state == DirectiveState.PartOf) {
      parser.reportRecoverableError(token, messageNonPartOfDirectiveInPart);
    } else {
      parser.reportRecoverableError(token, messageDirectiveAfterDeclaration);
    }
  }

  void checkLibrary(Parser parser, Token token) {
    if (state.index < DirectiveState.Library.index) {
      state = DirectiveState.Library;
      return;
    }
    // Recovery
    if (state == DirectiveState.PartOf) {
      parser.reportRecoverableError(token, messageNonPartOfDirectiveInPart);
    } else {
      parser.reportRecoverableError(token, messageLibraryDirectiveNotFirst);
    }
  }

  void checkPart(Parser parser, Token token) {
    if (state.index <= DirectiveState.Part.index) {
      state = DirectiveState.Part;
      return;
    }
    // Recovery
    if (state == DirectiveState.PartOf) {
      parser.reportRecoverableError(token, messageNonPartOfDirectiveInPart);
    } else {
      parser.reportRecoverableError(token, messageDirectiveAfterDeclaration);
    }
  }

  void checkPartOf(Parser parser, Token token) {
    if (state == DirectiveState.Unknown) {
      state = DirectiveState.PartOf;
      return;
    }
    // Recovery
    if (state == DirectiveState.PartOf) {
      parser.reportRecoverableError(token, messagePartOfTwice);
    } else {
      parser.reportRecoverableError(token, messageNonPartOfDirectiveInPart);
    }
  }
}

enum DirectiveState {
  Unknown,
  Script,
  Library,
  ImportAndExport,
  Part,
  PartOf,
  Declarations,
}
