// Copyright (c) 2021, 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 'dart:async';

import '../executor.dart';
import '../api.dart';
import 'serialization.dart';
import 'serialization_extensions.dart';

/// Implementation of [MacroClassIdentifier].
class MacroClassIdentifierImpl implements MacroClassIdentifier {
  final String id;

  MacroClassIdentifierImpl(Uri library, String name) : id = '$library#$name';

  MacroClassIdentifierImpl.deserialize(Deserializer deserializer)
      : id = (deserializer..moveNext()).expectString();

  void serialize(Serializer serializer) => serializer.addString(id);

  operator ==(other) => other is MacroClassIdentifierImpl && id == other.id;

  int get hashCode => id.hashCode;
}

/// Implementation of [MacroInstanceIdentifier].
class MacroInstanceIdentifierImpl implements MacroInstanceIdentifier {
  static int _next = 0;

  final int id;

  MacroInstanceIdentifierImpl() : id = _next++;

  MacroInstanceIdentifierImpl.deserialize(Deserializer deserializer)
      : id = (deserializer..moveNext()).expectNum();

  void serialize(Serializer serializer) => serializer.addNum(id);

  operator ==(other) => other is MacroInstanceIdentifierImpl && id == other.id;

  int get hashCode => id;
}

/// Implementation of [MacroExecutionResult].
class MacroExecutionResultImpl implements MacroExecutionResult {
  @override
  final List<DeclarationCode> augmentations;

  @override
  final List<DeclarationCode> imports;

  MacroExecutionResultImpl({
    List<DeclarationCode>? augmentations,
    List<DeclarationCode>? imports,
  })  : augmentations = augmentations ?? [],
        imports = imports ?? [];

  factory MacroExecutionResultImpl.deserialize(Deserializer deserializer) {
    deserializer.moveNext();
    deserializer.expectList();
    List<DeclarationCode> augmentations = [
      for (bool hasNext = deserializer.moveNext();
          hasNext;
          hasNext = deserializer.moveNext())
        deserializer.expectCode()
    ];
    deserializer.moveNext();
    deserializer.expectList();
    List<DeclarationCode> imports = [
      for (bool hasNext = deserializer.moveNext();
          hasNext;
          hasNext = deserializer.moveNext())
        deserializer.expectCode()
    ];

    return new MacroExecutionResultImpl(
      augmentations: augmentations,
      imports: imports,
    );
  }

  void serialize(Serializer serializer) {
    serializer.startList();
    for (DeclarationCode augmentation in augmentations) {
      augmentation.serialize(serializer);
    }
    serializer.endList();
    serializer.startList();
    for (DeclarationCode import in imports) {
      import.serialize(serializer);
    }
    serializer.endList();
  }
}

/// Implementation of [FunctionDefinitionBuilder].
class FunctionDefinitionBuilderImpl implements FunctionDefinitionBuilder {
  final TypeResolver typeResolver;
  final TypeDeclarationResolver typeDeclarationResolver;
  final ClassIntrospector classIntrospector;

  /// The declaration this is a builder for.
  final FunctionDeclaration declaration;

  /// The final result, will be built up over `augment` calls.
  final MacroExecutionResultImpl result;

  FunctionDefinitionBuilderImpl(this.declaration, this.typeResolver,
      this.typeDeclarationResolver, this.classIntrospector)
      : result = new MacroExecutionResultImpl();

  FunctionDefinitionBuilderImpl.deserialize(Deserializer deserializer,
      this.typeResolver, this.typeDeclarationResolver, this.classIntrospector)
      : declaration =
            (deserializer..moveNext()).expectDeclaration<FunctionDeclaration>(),
        result = new MacroExecutionResultImpl.deserialize(deserializer);

  void serialize(Serializer serializer) {
    // Note that the `typeResolver`, `typeDeclarationResolver`, and
    // `classIntrospector` are not serialized. These have custom implementations
    // on the client/server side.
    declaration.serialize(serializer);
    result.serialize(serializer);
  }

  @override
  void augment(FunctionBodyCode body) {
    result.augmentations.add(new DeclarationCode.fromParts([
      'augment ',
      declaration.returnType.code,
      ' ',
      declaration.name,
      if (declaration.typeParameters.isNotEmpty) ...[
        '<',
        for (TypeParameterDeclaration typeParam
            in declaration.typeParameters) ...[
          typeParam.name,
          if (typeParam.bounds != null) ...['extends ', typeParam.bounds!.code],
          if (typeParam != declaration.typeParameters.last) ', ',
        ],
        '>',
      ],
      '(',
      for (ParameterDeclaration positionalRequired
          in declaration.positionalParameters.where((p) => p.isRequired)) ...[
        new ParameterCode.fromParts([
          positionalRequired.type.code,
          ' ',
          positionalRequired.name,
        ]),
        ', '
      ],
      if (declaration.positionalParameters.any((p) => !p.isRequired)) ...[
        '[',
        for (ParameterDeclaration positionalOptional in declaration
            .positionalParameters
            .where((p) => !p.isRequired)) ...[
          new ParameterCode.fromParts([
            positionalOptional.type.code,
            ' ',
            positionalOptional.name,
          ]),
          ', ',
        ],
        ']',
      ],
      if (declaration.namedParameters.isNotEmpty) ...[
        '{',
        for (ParameterDeclaration named in declaration.namedParameters) ...[
          new ParameterCode.fromParts([
            if (named.isRequired) 'required ',
            named.type.code,
            ' ',
            named.name,
            if (named.defaultValue != null) ...[
              ' = ',
              named.defaultValue!,
            ],
          ]),
          ', ',
        ],
        '}',
      ],
      ') ',
      body,
    ]));
  }

  @override
  Future<List<ConstructorDeclaration>> constructorsOf(ClassDeclaration clazz) =>
      classIntrospector.constructorsOf(clazz);

  @override
  Future<List<FieldDeclaration>> fieldsOf(ClassDeclaration clazz) =>
      classIntrospector.fieldsOf(clazz);

  @override
  Future<List<ClassDeclaration>> interfacesOf(ClassDeclaration clazz) =>
      classIntrospector.interfacesOf(clazz);

  @override
  Future<List<MethodDeclaration>> methodsOf(ClassDeclaration clazz) =>
      classIntrospector.methodsOf(clazz);

  @override
  Future<List<ClassDeclaration>> mixinsOf(ClassDeclaration clazz) =>
      classIntrospector.mixinsOf(clazz);

  @override
  Future<TypeDeclaration> declarationOf(NamedStaticType annotation) =>
      typeDeclarationResolver.declarationOf(annotation);

  @override
  Future<ClassDeclaration?> superclassOf(ClassDeclaration clazz) =>
      classIntrospector.superclassOf(clazz);

  @override
  Future<StaticType> resolve(TypeAnnotation typeAnnotation) =>
      typeResolver.resolve(typeAnnotation);
}
