// 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 'package:_fe_analyzer_shared/src/macros/api.dart';

macro

class FunctionDefinitionMacro1 implements FunctionDefinitionMacro {
  const FunctionDefinitionMacro1();

  FutureOr<void> buildDefinitionForFunction(FunctionDeclaration function,
      FunctionDefinitionBuilder builder) {
    builder.augment(new FunctionBodyCode.fromString('''{
  throw 42;
}'''));
  }
}

macro

class FunctionDefinitionMacro2 implements FunctionDefinitionMacro {
  const FunctionDefinitionMacro2();

  FutureOr<void> buildDefinitionForFunction(FunctionDeclaration function,
      FunctionDefinitionBuilder builder) async {
    if (function.positionalParameters.isEmpty) {
      return;
    }
    StaticType returnType = await builder.resolve(function.returnType.code);
    StaticType parameterType =
    await builder.resolve(function.positionalParameters.first.type.code);
    builder.augment(new FunctionBodyCode.fromString('''{
  print('isExactly=${await returnType.isExactly(parameterType)}');
  print('isSubtype=${await returnType.isSubtypeOf(parameterType)}');
  throw 42;
}'''));
  }
}


macro

class FunctionTypesMacro1 implements FunctionTypesMacro {
  const FunctionTypesMacro1();

  FutureOr<void> buildTypesForFunction(FunctionDeclaration function,
      TypeBuilder builder) {
    var name = '${function.identifier.name}GeneratedClass';
    builder.declareType(
        name, new DeclarationCode.fromParts(['''
class $name {
  external ''', function.returnType.code, ''' method();
}'''
    ]));
  }
}

macro

class FunctionDeclarationsMacro1 implements FunctionDeclarationsMacro {
  const FunctionDeclarationsMacro1();

  FutureOr<void> buildDeclarationsForFunction(FunctionDeclaration function,
      DeclarationBuilder builder) {
    StringBuffer sb = new StringBuffer();
    if (function.isAbstract) {
      sb.write('a');
    }
    if (function.isExternal) {
      sb.write('e');
    }
    if (function.isGetter) {
      sb.write('g');
    }
    if (function.isOperator) {
      sb.write('o');
    }
    if (function.isSetter) {
      sb.write('s');
    }
    builder.declareInLibrary(new DeclarationCode.fromString('''
void ${function.identifier.name}GeneratedMethod_${sb}() {}
'''));
  }
}

macro

class FunctionDeclarationsMacro2 implements FunctionDeclarationsMacro {
  const FunctionDeclarationsMacro2();

  FutureOr<void> buildDeclarationsForFunction(FunctionDeclaration function,
      DeclarationBuilder builder) async {
    if (function.positionalParameters.isEmpty) {
      return;
    }
    StaticType returnType = await builder.resolve(function.returnType.code);
    StaticType parameterType =
    await builder.resolve(function.positionalParameters.first.type.code);
    bool isExactly = await returnType.isExactly(parameterType);
    bool isSubtype = await returnType.isSubtypeOf(parameterType);
    String tag = '${isExactly ? 'e' : ''}${isSubtype ? 's' : ''}';
    builder.declareInLibrary(new DeclarationCode.fromString('''
void ${function.identifier.name}GeneratedMethod_$tag() {}
'''));
  }
}

macro

class MethodDeclarationsMacro1 implements MethodDeclarationsMacro {
  const MethodDeclarationsMacro1();

  FutureOr<void> buildDeclarationsForMethod(MethodDeclaration method,
      ClassMemberDeclarationBuilder builder) {
    StringBuffer sb = new StringBuffer();
    if (method.isAbstract) {
      sb.write('a');
    }
    if (method.isExternal) {
      sb.write('e');
    }
    if (method.isGetter) {
      sb.write('g');
    }
    if (method.isOperator) {
      sb.write('o');
    }
    if (method.isSetter) {
      sb.write('s');
    }
    String name;
    if (method.isOperator) {
      name = 'operator';
    } else {
      name = method.identifier.name;
    }
    builder.declareInLibrary(new DeclarationCode.fromString('''
void ${method.definingClass.name}_${name}GeneratedMethod_${sb}() {}
'''));
  }
}

macro

class VariableDeclarationsMacro1 implements VariableDeclarationsMacro {
  const VariableDeclarationsMacro1();

  FutureOr<void> buildDeclarationsForVariable(VariableDeclaration variable,
      DeclarationBuilder builder) {
    StringBuffer sb = new StringBuffer();
    if (variable.isExternal) {
      sb.write('e');
    }
    if (variable.isFinal) {
      sb.write('f');
    }
    if (variable.isLate) {
      sb.write('l');
    }
    builder.declareInLibrary(new DeclarationCode.fromString('''
void ${variable.identifier.name}GeneratedMethod_${sb}() {}
'''));
  }
}

macro

class FieldDeclarationsMacro1 implements FieldDeclarationsMacro {
  const FieldDeclarationsMacro1();

  FutureOr<void> buildDeclarationsForField(FieldDeclaration field,
      ClassMemberDeclarationBuilder builder) {
    StringBuffer sb = new StringBuffer();
    if (field.isExternal) {
      sb.write('e');
    }
    if (field.isFinal) {
      sb.write('f');
    }
    if (field.isLate) {
      sb.write('l');
    }
    builder.declareInLibrary(new DeclarationCode.fromString('''
void ${field.definingClass.name}_${field.identifier.name}GeneratedMethod_${sb}() {}
'''));
  }
}

macro

class ClassDeclarationsMacro1 implements ClassDeclarationsMacro {
  const ClassDeclarationsMacro1();

  FutureOr<void> buildDeclarationsForClass(ClassDeclaration clazz,
      ClassMemberDeclarationBuilder builder) {
    StringBuffer sb = new StringBuffer();
    if (clazz.isAbstract) {
      sb.write('a');
    }
    if (clazz.isExternal) {
      sb.write('e');
    }
    builder.declareInLibrary(new DeclarationCode.fromString('''
void ${clazz.identifier.name}GeneratedMethod_${sb}() {}
'''));
  }
}

macro

class ClassDeclarationsMacro2 implements ClassDeclarationsMacro {
  const ClassDeclarationsMacro2();

  FutureOr<void> buildDeclarationsForClass(ClassDeclaration clazz,
      ClassMemberDeclarationBuilder builder) async {
    List<ConstructorDeclaration> constructors = await builder.constructorsOf(
        clazz);
    StringBuffer constructorsText = new StringBuffer();
    String comma = '';
    constructorsText.write('constructors=');
    for (ConstructorDeclaration constructor in constructors) {
      constructorsText.write(comma);
      String name = constructor.identifier.name;
      constructorsText.write("'$name'");
      comma = ',';
    }

    List<FieldDeclaration> fields = await builder.fieldsOf(
        clazz);
    StringBuffer fieldsText = new StringBuffer();
    comma = '';
    fieldsText.write('fields=');
    for (FieldDeclaration field in fields) {
      fieldsText.write(comma);
      String name = field.identifier.name;
      fieldsText.write("'$name'");
      comma = ',';
    }

    List<MethodDeclaration> methods = await builder.methodsOf(
        clazz);
    StringBuffer methodsText = new StringBuffer();
    comma = '';
    methodsText.write('methods=');
    for (MethodDeclaration method in methods) {
      methodsText.write(comma);
      String name = method.identifier.name;
      methodsText.write("'$name'");
      comma = ',';
    }

    builder.declareInLibrary(new DeclarationCode.fromString('''
void ${clazz.identifier.name}Introspection() {
  print("$constructorsText");
  print("$fieldsText");
  print("$methodsText");
}
'''));
  }
}

macro

class ConstructorDeclarationsMacro1
    implements ConstructorDeclarationsMacro {
  const ConstructorDeclarationsMacro1();

  FutureOr<void> buildDeclarationsForConstructor(
      ConstructorDeclaration constructor,
      ClassMemberDeclarationBuilder builder) {
    StringBuffer sb = new StringBuffer();
    if (constructor.isAbstract) {
      sb.write('a');
    }
    if (constructor.isExternal) {
      sb.write('e');
    }
    if (constructor.isGetter) {
      sb.write('g');
    }
    if (constructor.isOperator) {
      sb.write('o');
    }
    if (constructor.isSetter) {
      sb.write('s');
    }
    if (constructor.isFactory) {
      sb.write('f');
    }
    builder.declareInClass(new DeclarationCode.fromString('''
void ${constructor.definingClass.name}_${constructor.identifier
        .name}GeneratedMethod_${sb}() {}
'''));
  }
}

macro

class ToStringMacro implements ClassDeclarationsMacro {
  const ToStringMacro();

  FutureOr<void> buildDeclarationsForClass(ClassDeclaration clazz,
      ClassMemberDeclarationBuilder builder) async {
    Iterable<MethodDeclaration> methods = await builder.methodsOf(clazz);
    if (!methods.any((m) => m.identifier.name == 'toString')) {
      Iterable<FieldDeclaration> fields = await builder.fieldsOf(clazz);
      List<Object> parts = ['''
  toString() {
    return "${clazz.identifier.name}('''
      ];
      String comma = '';
      for (FieldDeclaration field in fields) {
        parts.add(comma);
        parts.add('${field.identifier.name}=\${');
        parts.add(field.identifier.name);
        parts.add('}');
        comma = ',';
      }
      parts.add(''')";
  }''');
      builder.declareInClass(new DeclarationCode.fromParts(parts));
    }
  }
}

macro

class SequenceMacro
    implements
        ClassDeclarationsMacro,
        MethodDeclarationsMacro {
  final int index;

  const SequenceMacro(this.index);

  void _addMethod(ClassDeclaration clazz,
      ClassMemberDeclarationBuilder builder) async {
  }

  Future<void> _findAllMethods(ClassMemberDeclarationBuilder builder,
      ClassDeclaration cls, List<MethodDeclaration> methods) async {
    ClassDeclaration? superclass = await builder.superclassOf(cls);
    if (superclass != null) {
      await _findAllMethods(builder, superclass, methods);
    }
    for (ClassDeclaration mixin in await builder.mixinsOf(cls)) {
      await _findAllMethods(builder, mixin, methods);
    }
    for (ClassDeclaration interface in await builder.interfacesOf(cls)) {
      await _findAllMethods(builder, interface, methods);
    }
    methods.addAll(await builder.methodsOf(cls));
  }

  FutureOr<void> buildDeclarationsForClass(ClassDeclaration clazz,
      ClassMemberDeclarationBuilder builder) async {
    List<MethodDeclaration> methods = [];
    await _findAllMethods(builder, clazz, methods);
    int index = 0;
    String suffix = '';
    while (methods.any((m) => m.identifier.name == 'method$suffix')) {
      index++;
      suffix = '$index';
    }
    builder.declareInClass(new DeclarationCode.fromString('''
  method$suffix() {}'''));
  }

  FutureOr<void> buildDeclarationsForMethod(MethodDeclaration method,
      ClassMemberDeclarationBuilder builder) {
    // Do nothing. The applying of this will show up in the declarations phase
    // application order.
  }
}

macro

class SupertypesMacro implements ClassDefinitionMacro {
  const SupertypesMacro();

  FutureOr<void> buildDefinitionForClass(ClassDeclaration clazz,
      ClassDefinitionBuilder builder) async {
    ClassDeclaration? superClass = await builder.superclassOf(clazz);
    FunctionDefinitionBuilder getSuperClassBuilder = await builder.buildMethod(
        (await builder.methodsOf(clazz))
            .firstWhere((m) => m.identifier.name == 'getSuperClass')
            .identifier);
    getSuperClassBuilder.augment(new FunctionBodyCode.fromString('''{
    return "${superClass?.identifier.name}";
  }'''));
  }
}

macro

class ImportConflictMacro implements FunctionDefinitionMacro {
  const ImportConflictMacro();

  FutureOr<void> buildDefinitionForFunction(FunctionDeclaration function,
      FunctionDefinitionBuilder builder) {
    builder.augment(new FunctionBodyCode.fromParts([
      '{\n  ',
      'var ',
      'prefix',
      ' = ',
      function.positionalParameters
          .elementAt(0)
          .type
          .code,
      ';\n  ',
      'var prefix0',
      ' = ',
      function.positionalParameters
          .elementAt(1)
          .type
          .code,
      ';\n  ',
      'var pre',
      'fix',
      '10 = ',
      function.positionalParameters
          .elementAt(2)
          .type
          .code,
      ';\n',
      '}',
    ]));
  }
}

macro

class InferableMacro
    implements
        FieldDeclarationsMacro,
        MethodDeclarationsMacro,
        ConstructorDeclarationsMacro {
  const InferableMacro();

  FutureOr<void> buildDeclarationsForField(FieldDeclaration field,
      ClassMemberDeclarationBuilder builder) async {
    Identifier listIdentifier = await builder.resolveIdentifier(
        Uri.parse('dart:core'), 'List');
    builder.declareInClass(new DeclarationCode.fromParts([
      field.type.code,
      ' get_${field.identifier.name}(',
      field.type.code,
      ' f) => ',
      field.identifier,
      ';',
    ]));
    builder.declareInClass(new DeclarationCode.fromParts([
      field.type.code,
      ' Function() get_${field.identifier.name}Func(',
      field.type.code,
      ' Function(',
      field.type.code,
      ') f) => () => ',
      field.identifier,
      ';',
    ]));
    builder.declareInClass(new DeclarationCode.fromParts([
      listIdentifier,
      '<',
      field.type.code,
      '> get_${field.identifier.name}List(',
      listIdentifier,
      '<',
      field.type.code,
      '> l) => [',
      field.identifier,
      '];',
    ]));
    // TODO(johnniwinther): Enable these when field augmentation is supported.
    /*builder.declareInClass(new DeclarationCode.fromParts([
      field.type.code,
      ' field_${field.identifier.name} = ',
      field.identifier,
      ';',
    ]));
    builder.declareInClass(new DeclarationCode.fromParts([
      field.type.code,
      ' Function() field_${field.identifier.name}Func = () => ',
      field.identifier,
      ';',
    ]));
    builder.declareInClass(new DeclarationCode.fromParts([
      listIdentifier,
      '<',
      field.type.code,
      '> field_${field.identifier.name}List = [',
      field.identifier,
      '];',
    ]));*/
  }

  FutureOr<void> buildDeclarationsForMethod(MethodDeclaration method,
      ClassMemberDeclarationBuilder builder) async {
    Identifier listIdentifier = await builder.resolveIdentifier(
        Uri.parse('dart:core'), 'List');
    builder.declareInClass(new DeclarationCode.fromParts([
      method.returnType.code,
      ' get_${method.identifier.name}() => ',
      method.identifier,
      '();',
    ]));
    builder.declareInClass(new DeclarationCode.fromParts([
      method.returnType.code,
      ' Function() get_${method.identifier.name}Func() => () => ',
      method.identifier,
      '();',
    ]));
    builder.declareInClass(new DeclarationCode.fromParts([
      listIdentifier,
      '<',
      method.returnType.code,
      '> get_${method.identifier.name}List() => [',
      method.identifier,
      '()];',
    ]));
  }

  FutureOr<void> buildDeclarationsForConstructor(
      ConstructorDeclaration constructor,
      ClassMemberDeclarationBuilder builder) async {
    Identifier listIdentifier = await builder.resolveIdentifier(
        Uri.parse('dart:core'), 'List');
    builder.declareInClass(new DeclarationCode.fromParts([
      constructor.positionalParameters.first.type.code,
      ' get_${constructor.identifier.name}() => throw "";',
    ]));
    builder.declareInClass(new DeclarationCode.fromParts([
      constructor.positionalParameters.first.type.code,
      ' Function() get_${constructor.identifier.name}Func() => throw "";',
    ]));
    builder.declareInClass(new DeclarationCode.fromParts([
      listIdentifier,
      '<',
      constructor.positionalParameters.first.type.code,
      '> get_${constructor.identifier.name}List() => throw "";',
    ]));
  }
}