// 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:_fe_analyzer_shared/src/messages/codes.dart'
    show
        LocatedMessage,
        Message,
        templateExperimentNotEnabled,
        templateInternalProblemUnsupported;
import 'package:_fe_analyzer_shared/src/parser/parser.dart';
import 'package:_fe_analyzer_shared/src/parser/stack_listener.dart';
import 'package:_fe_analyzer_shared/src/scanner/token.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:collection/collection.dart';
import 'package:pub_semver/pub_semver.dart';

/// "Mini AST" representation of a declaration which can accept annotations.
class AnnotatedNode {
  final Comment? documentationComment;

  final List<Annotation> metadata;

  AnnotatedNode(this.documentationComment, List<Annotation>? metadata)
      : metadata = metadata ?? const [];
}

/// "Mini AST" representation of an annotation.
class Annotation {
  final String name;

  final String? constructorName;

  final List<Expression>? arguments;

  Annotation(this.name, this.constructorName, this.arguments);
}

/// "Mini AST" representation of a class declaration.
class ClassDeclaration extends CompilationUnitMember {
  final String name;

  final TypeName? superclass;

  final List<ClassMember> members;

  ClassDeclaration(Comment? documentationComment, List<Annotation>? metadata,
      this.name, this.superclass, this.members)
      : super(documentationComment, metadata);
}

/// "Mini AST" representation of a class member.
class ClassMember extends AnnotatedNode {
  ClassMember(Comment? documentationComment, List<Annotation>? metadata)
      : super(documentationComment, metadata);
}

/// "Mini AST" representation of a comment.
class Comment {
  final bool isDocumentation;

  final List<Token> tokens;

  factory Comment(Token commentToken) {
    var tokens = <Token>[];
    bool isDocumentation = false;

    Token? token = commentToken;
    while (token != null) {
      if (token.lexeme.startsWith('/**') || token.lexeme.startsWith('///')) {
        isDocumentation = true;
      }
      tokens.add(token);
      token = token.next;
    }
    return Comment._(isDocumentation, tokens);
  }

  Comment._(this.isDocumentation, this.tokens);
}

/// "Mini AST" representation of a CompilationUnit.
class CompilationUnit {
  final declarations = <CompilationUnitMember>[];
}

/// "Mini AST" representation of a top level member of a compilation unit.
class CompilationUnitMember extends AnnotatedNode {
  CompilationUnitMember(
      Comment? documentationComment, List<Annotation>? metadata)
      : super(documentationComment, metadata);
}

/// "Mini AST" representation of a constructor declaration.
class ConstructorDeclaration extends ClassMember {
  final String name;

  ConstructorDeclaration(
      Comment? documentationComment, List<Annotation>? metadata, this.name)
      : super(documentationComment, metadata);
}

/// "Mini AST" representation of an individual enum constant in an enum
/// declaration.
class EnumConstantDeclaration extends AnnotatedNode {
  final String name;

  EnumConstantDeclaration(
      Comment? documentationComment, List<Annotation>? metadata, this.name)
      : super(documentationComment, metadata);
}

/// "Mini AST" representation of an enum declaration.
class EnumDeclaration extends CompilationUnitMember {
  final String name;

  final List<EnumConstantDeclaration> constants;

  EnumDeclaration(Comment? documentationComment, List<Annotation>? metadata,
      this.name, this.constants)
      : super(documentationComment, metadata);
}

/// "Mini AST" representation of an expression.
class Expression {
  String toCode() {
    throw UnimplementedError('$runtimeType');
  }
}

/// "Mini AST" representation of an integer literal.
class IntegerLiteral extends Expression {
  final int value;

  IntegerLiteral(this.value);
}

/// "Mini AST" representation of a list literal.
class ListLiteral extends Expression {
  final Token leftBracket;
  final List<Expression> elements;
  final Token rightBracket;

  ListLiteral(this.leftBracket, this.elements, this.rightBracket);

  @override
  String toCode() {
    return '[' + elements.map((e) => e.toCode()).join(', ') + ']';
  }
}

/// "Mini AST" representation of a method declaration.
class MethodDeclaration extends ClassMember {
  final bool isGetter;

  final String name;

  final TypeName? returnType;

  MethodDeclaration(Comment? documentationComment, List<Annotation>? metadata,
      this.isGetter, this.name, this.returnType)
      : super(documentationComment, metadata);
}

/// Parser listener which generates a "mini AST" representation of the source
/// code.  This representation is just sufficient for summary code generation.
class MiniAstBuilder extends StackListener {
  bool inMetadata = false;

  final compilationUnit = CompilationUnit();

  @override
  Uri get uri => throw UnimplementedError();

  @override
  void addProblem(Message message, int charOffset, int length,
      {bool wasHandled = false, List<LocatedMessage>? context}) {
    internalProblem(message, charOffset, uri);
  }

  @override
  void beginMetadata(Token token) {
    inMetadata = true;
  }

  @override
  void beginMetadataStar(Token token) {
    debugEvent("beginMetadataStar");
    var precedingComments = token.precedingComments;
    if (precedingComments != null) {
      push(Comment(precedingComments));
    } else {
      push(NullValue.Comments);
    }
  }

  @override
  void endArguments(int count, Token beginToken, Token endToken) {
    debugEvent("Arguments");
    push(popList(count, List<dynamic>.filled(count, null, growable: true)));
  }

  @override
  void endBinaryExpression(Token token) {
    debugEvent("BinaryExpression");

    if (identical('.', token.stringValue)) {
      var rightOperand = pop() as String;
      var leftOperand = pop();
      if (leftOperand is String && !leftOperand.contains('.')) {
        push(PrefixedIdentifier(leftOperand, token, rightOperand));
      } else {
        push(UnknownExpression());
      }
    } else {
      pop(); // RHS
      pop(); // LHS
      push(UnknownExpression());
    }
  }

  @override
  void endClassDeclaration(Token beginToken, Token endToken) {
    debugEvent("ClassDeclaration");
    var members = popTypedList<ClassMember>() ?? [];
    var superclass = pop() as TypeName?;
    pop(); // Type variables
    var name = pop() as String;
    var metadata = popTypedList<Annotation>();
    var comment = pop() as Comment?;
    compilationUnit.declarations
        .add(ClassDeclaration(comment, metadata, name, superclass, members));
  }

  @override
  void endClassFactoryMethod(
      Token beginToken, Token factoryKeyword, Token endToken) {
    debugEvent("ClassFactoryMethod");
    pop(); // Body
    pop(); // Type variables
    var name = pop() as String;
    var metadata = popTypedList() as List<Annotation>?;
    var comment = pop() as Comment?;
    push(ConstructorDeclaration(comment, metadata, name));
  }

  @override
  void endClassMethod(Token? getOrSet, Token beginToken, Token beginParam,
      Token? beginInitializers, Token endToken) {
    debugEvent("Method");
    pop(); // Body
    pop(); // Initializers
    pop(); // Formal parameters
    pop(); // Type variables
    var name = pop() as String;
    var returnType = pop() as TypeName?;
    var metadata = popTypedList<Annotation>();
    var comment = pop() as Comment?;
    push(MethodDeclaration(
        comment, metadata, getOrSet?.lexeme == 'get', name, returnType));
  }

  @override
  void endClassOrMixinBody(
      DeclarationKind kind, int memberCount, Token beginToken, Token endToken) {
    debugEvent("ClassOrMixinBody");
    push(popList(memberCount,
        List<ClassMember?>.filled(memberCount, null, growable: true)));
  }

  @override
  void endCombinators(int count) {
    debugEvent("Combinators");
  }

  @override
  void endConditionalUris(int count) {
    debugEvent("ConditionalUris");
    if (count != 0) {
      internalProblem(
          templateInternalProblemUnsupported.withArguments("Conditional URIs"),
          -1,
          null);
    }
  }

  @override
  void endEnum(Token enumKeyword, Token leftBrace, int count) {
    debugEvent("Enum");
    var constants =
        List<EnumConstantDeclaration?>.filled(count, null, growable: true);
    popList(count, constants);
    var name = pop() as String;
    var metadata = popTypedList<Annotation>();
    var comment = pop() as Comment?;
    compilationUnit.declarations.add(EnumDeclaration(
        comment, metadata, name, constants.whereNotNull().toList()));
  }

  @override
  void endFieldInitializer(Token assignment, Token token) {
    debugEvent("FieldInitializer");
    pop(); // Expression
  }

  @override
  void endFormalParameter(
      Token? thisKeyword,
      Token? periodAfterThis,
      Token nameToken,
      Token? initializerStart,
      Token? initializerEnd,
      FormalParameterKind kind,
      MemberKind memberKind) {
    debugEvent("FormalParameter");
    pop(); // Name
    pop(); // Type
    pop(); // Metadata
    pop(); // Comment
  }

  @override
  void endFormalParameters(
      int count, Token beginToken, Token endToken, MemberKind kind) {
    debugEvent("FormalParameters");
  }

  @override
  void endImport(Token importKeyword, Token? semicolon) {
    debugEvent("Import");
    pop(NullValue.Prefix); // Prefix identifier
    pop(); // URI
    pop(); // Metadata
    pop(); // Comment
  }

  @override
  void endLibraryName(Token libraryKeyword, Token semicolon) {
    debugEvent("LibraryName");
    pop(); // Library name
    pop(); // Metadata
    pop(); // Comment
  }

  @override
  void endLiteralString(int interpolationCount, Token endToken) {
    super.endLiteralString(interpolationCount, endToken);
    var value = pop() as String;
    push(StringLiteral(value));
  }

  @override
  void endMember() {
    debugEvent("Member");
  }

  @override
  void endMetadata(Token beginToken, Token? periodBeforeName, Token endToken) {
    debugEvent("Metadata");
    inMetadata = false;
    var arguments = pop() as List?;
    var constructorName = popIfNotNull(periodBeforeName) as String?;
    pop(); // Type arguments
    var name = pop() as String;
    push(Annotation(name, constructorName,
        arguments == null ? null : arguments.cast<Expression>()));
  }

  @override
  void endMetadataStar(int count) {
    debugEvent("MetadataStar");
    push(
        popList(count, List<Annotation?>.filled(count, null, growable: true)) ??
            NullValue.Metadata);
  }

  @override
  void endShow(Token showKeyword) {
    debugEvent("Show");
    pop(); // Shown names
  }

  @override
  void endTopLevelFields(
      Token? externalToken,
      Token? staticToken,
      Token? covariantToken,
      Token? lateToken,
      Token? varFinalOrConst,
      int count,
      Token beginToken,
      Token endToken) {
    // We ignore top level variable declarations; they are present just to make
    // the IDL analyze without warnings.
    debugEvent("TopLevelFields");
    popList(count, List<dynamic>.filled(count, null, growable: true)); // Fields
    pop(); // Type
    pop(); // Metadata
    pop(); // Comment
  }

  @override
  void endTypeArguments(int count, Token beginToken, Token endToken) {
    debugEvent("TypeArguments");
    push(popList(count, List<TypeName?>.filled(count, null, growable: true)));
  }

  @override
  void handleAsyncModifier(Token? asyncToken, Token? starToken) {
    debugEvent("AsyncModifier");
  }

  @override
  void handleClassNoWithClause() {
    debugEvent("NoClassWithClause");
  }

  @override
  void handleClassWithClause(Token withKeyword) {
    debugEvent("ClassWithClause");
  }

  @override
  void handleFormalParameterWithoutValue(Token token) {
    debugEvent("FormalParameterWithoutValue");
  }

  @override
  void handleFunctionBodySkipped(Token token, bool isExpressionBody) {
    if (isExpressionBody) pop();
    push(NullValue.FunctionBody);
  }

  @override
  void handleIdentifier(Token token, IdentifierContext context) {
    if (context == IdentifierContext.enumValueDeclaration) {
      var metadata = popTypedList() as List<Annotation>?;
      var comment = pop() as Comment?;
      push(EnumConstantDeclaration(comment, metadata, token.lexeme));
    } else {
      push(token.lexeme);
    }
  }

  @override
  void handleIdentifierList(int count) {
    debugEvent("IdentifierList");
    push(popList(count, List<dynamic>.filled(count, null, growable: true)));
  }

  @override
  void handleImportPrefix(Token? deferredKeyword, Token? asKeyword) {
    debugEvent("ImportPrefix");
    pushIfNull(asKeyword, NullValue.Prefix);
  }

  @override
  void handleInvalidMember(Token endToken) {
    debugEvent("InvalidMember");
    pop(); // metadata star
  }

  @override
  void handleInvalidTopLevelDeclaration(Token endToken) {
    debugEvent("InvalidTopLevelDeclaration");
    pop(); // metadata star
  }

  @override
  void handleInvalidTypeArguments(Token token) {
    debugEvent("InvalidTypeArguments");
    pop(NullValue.TypeArguments);
  }

  @override
  void handleLiteralInt(Token token) {
    debugEvent("LiteralInt");
    push(IntegerLiteral(int.parse(token.lexeme)));
  }

  @override
  void handleLiteralList(
      int count, Token leftBracket, Token? constKeyword, Token rightBracket) {
    debugEvent("LiteralList");

    var elements = List<Object?>.filled(count, null);
    popList(count, elements);
    pop(); // type arguments

    push(
      ListLiteral(
        leftBracket,
        List<Expression>.from(elements),
        rightBracket,
      ),
    );
  }

  @override
  void handleLiteralNull(Token token) {
    debugEvent("LiteralNull");
    push(UnknownExpression());
  }

  @override
  void handleNamedArgument(Token colon) {
    var expression = pop() as Expression;
    var name = pop() as String;
    push(NamedExpression(name, colon, expression));
  }

  @override
  void handleNamedMixinApplicationWithClause(Token withKeyword) {
    debugEvent("NamedMixinApplicationWithClause");
  }

  @override
  void handleNativeClause(Token nativeToken, bool hasName) {
    debugEvent("NativeClause");
    if (hasName) {
      pop(); // Pop the native name which is a StringLiteral.
    }
  }

  @override
  void handleNativeFunctionBodyIgnored(Token nativeToken, Token semicolon) {
    debugEvent("NativeFunctionBodyIgnored");
  }

  @override
  void handleNativeFunctionBodySkipped(Token nativeToken, Token semicolon) {
    debugEvent("NativeFunctionBodySkipped");
    push(NullValue.FunctionBody);
  }

  @override
  void handleNonNullAssertExpression(Token bang) {
    reportNonNullAssertExpressionNotEnabled(bang);
  }

  @override
  void handleQualified(Token period) {
    debugEvent("Qualified");
    var suffix = pop() as String;
    var prefix = pop() as String;
    push('$prefix.$suffix');
  }

  @override
  void handleRecoverClassHeader() {
    pop(); // superclass
  }

  @override
  void handleRecoverImport(Token? semicolon) {
    debugEvent("RecoverImport");
    pop(NullValue.Prefix); // Prefix identifier
  }

  @override
  void handleSend(Token beginToken, Token endToken) {
    debugEvent("Send");

    var arguments = pop();
    pop(); // Type arguments
    if (arguments != null) {
      pop(); // Receiver
      push(UnknownExpression());
    } else {
      // Property get.
    }
  }

  @override
  void handleType(Token beginToken, Token? questionMark) {
    debugEvent("Type");
    // reportErrorIfNullableType(questionMark);
    var typeArguments = popTypedList<TypeName>();
    var name = pop() as String;
    push(TypeName(name, typeArguments));
  }

  @override
  internalProblem(Message message, int charOffset, Uri? uri) {
    throw UnsupportedError(message.message);
  }

  List? popList(int n, List list) {
    if (n == 0) return null;
    return stack.popList(n, list, null);
  }

  /// Calls [pop] and creates a list with the appropriate type parameter `T`
  /// from the resulting `List<dynamic>`.
  List<T>? popTypedList<T>() {
    var list = pop() as List?;
    return list != null ? List<T>.from(list) : null;
  }

  void reportErrorIfNullableType(Token? questionMark) {
    if (questionMark != null) {
      assert(optional('?', questionMark));
      var feature = ExperimentalFeatures.non_nullable;
      handleRecoverableError(
        templateExperimentNotEnabled.withArguments(
          feature.enableString,
          _versionAsString(ExperimentStatus.currentVersion),
        ),
        questionMark,
        questionMark,
      );
    }
  }

  void reportNonNullAssertExpressionNotEnabled(Token bang) {
    var feature = ExperimentalFeatures.non_nullable;
    handleRecoverableError(
      templateExperimentNotEnabled.withArguments(
        feature.enableString,
        _versionAsString(ExperimentStatus.currentVersion),
      ),
      bang,
      bang,
    );
  }

  static String _versionAsString(Version version) {
    return '${version.major}.${version.minor}.${version.patch}';
  }
}

/// Parser intended for use with [MiniAstBuilder].
class MiniAstParser extends Parser {
  MiniAstParser(MiniAstBuilder listener) : super(listener);

  @override
  Token parseArgumentsOpt(Token token) {
    var listener = this.listener as MiniAstBuilder;
    if (listener.inMetadata) {
      return super.parseArgumentsOpt(token);
    } else {
      return skipArgumentsOpt(token);
    }
  }

  @override
  Token parseFunctionBody(Token token, bool isExpression, bool allowAbstract) {
    return skipFunctionBody(token, isExpression, allowAbstract);
  }

  @override
  Token parseInvalidBlock(Token token) => skipBlock(token);
}

/// "Mini AST" representation of a named expression.
class NamedExpression extends Expression {
  final String name;
  final Token colon;
  final Expression expression;

  NamedExpression(this.name, this.colon, this.expression);
}

/// "Mini AST" representation of a named expression.
class PrefixedIdentifier extends Expression {
  final String prefix;
  final Token operator;
  final String identifier;

  PrefixedIdentifier(this.prefix, this.operator, this.identifier);

  @override
  String toCode() {
    return '$prefix.$identifier';
  }
}

/// "Mini AST" representation of a string literal.
class StringLiteral extends Expression {
  final String stringValue;

  StringLiteral(this.stringValue);
}

/// "Mini AST" representation of a type name.
class TypeName {
  final String name;

  final List<TypeName>? typeArguments;

  TypeName(this.name, this.typeArguments);
}

/// "Mini AST" representation of an expression which summary code generation
/// need not be concerned about.
class UnknownExpression extends Expression {}
