// 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.

/// Listener used in combination with `TopLevelParser` to extract the URIs of
/// import, part, and export directives.
library front_end.src.fasta.source.directive_listener;

import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
import 'package:_fe_analyzer_shared/src/parser/identifier_context.dart';
import 'package:_fe_analyzer_shared/src/parser/listener.dart';
import 'package:_fe_analyzer_shared/src/parser/quote.dart';
import '../fasta_codes.dart' show messageExpectedBlockToSkip;

/// Listener that records imports, exports, and part directives.
///
/// This is normally used in combination with the `TopLevelParser`, which skips
/// over the body of declarations like classes and function that are irrelevant
/// for directives. Note that on correct programs directives cannot occur after
/// any top-level declaration, but we recommend to continue parsing the entire
/// file in order to gracefully handle input errors.
class DirectiveListener extends Listener {
  /// Import directives with URIs and combinators.
  final List<NamespaceDirective> imports = <NamespaceDirective>[];

  /// Export directives with URIs and combinators.
  final List<NamespaceDirective> exports = <NamespaceDirective>[];

  /// Collects URIs that occur on any part directive.
  final Set<String?> parts = new Set<String?>();

  bool _inPart = false;
  String? _uri;
  List<NamespaceCombinator>? _combinators;
  List<String>? _combinatorNames;

  DirectiveListener();

  @override
  beginExport(Token export) {
    _combinators = <NamespaceCombinator>[];
  }

  @override
  void beginHide(Token hide) {
    _combinatorNames = <String>[];
  }

  @override
  beginImport(Token import) {
    _combinators = <NamespaceCombinator>[];
  }

  @override
  void beginLiteralString(Token token) {
    if (_combinators != null || _inPart) {
      _uri = unescapeString(token.lexeme, token, this);
    }
  }

  @override
  beginPart(Token part) {
    _inPart = true;
  }

  @override
  void beginShow(Token show) {
    _combinatorNames = <String>[];
  }

  @override
  endExport(Token export, Token semicolon) {
    exports.add(new NamespaceDirective.export(_uri, _combinators));
    _uri = null;
    _combinators = null;
  }

  @override
  void endHide(Token hide) {
    _combinators!.add(new NamespaceCombinator.hide(_combinatorNames!));
    _combinatorNames = null;
  }

  @override
  endImport(Token? import, Token? semicolon) {
    imports.add(new NamespaceDirective.import(_uri, _combinators));
    _uri = null;
    _combinators = null;
  }

  @override
  endPart(Token part, Token semicolon) {
    parts.add(_uri);
    _uri = null;
    _inPart = false;
  }

  @override
  void endShow(Token show) {
    _combinators!.add(new NamespaceCombinator.show(_combinatorNames!));
    _combinatorNames = null;
  }

  @override
  void handleIdentifier(Token token, IdentifierContext context) {
    if (_combinatorNames != null && context == IdentifierContext.combinator) {
      _combinatorNames!.add(token.lexeme);
    }
  }

  /// By default, native clauses are not handled and an error is thrown.
  @override
  void handleNativeFunctionBodySkipped(Token nativeToken, Token semicolon) {
    super.handleRecoverableError(
        messageExpectedBlockToSkip, nativeToken, nativeToken);
  }
}

class NamespaceCombinator {
  final bool isShow;
  final Set<String> names;

  NamespaceCombinator.hide(List<String> names)
      : isShow = false,
        names = names.toSet();

  NamespaceCombinator.show(List<String> names)
      : isShow = true,
        names = names.toSet();
}

class NamespaceDirective {
  final bool isImport;
  final String? uri;
  final List<NamespaceCombinator>? combinators;

  NamespaceDirective.export(this.uri, this.combinators) : isImport = false;

  NamespaceDirective.import(this.uri, this.combinators) : isImport = true;
}
