// Copyright (c) 2022, 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';
import 'dart:collection';

macro

class DataClass implements ClassDeclarationsMacro, ClassDefinitionMacro {
  const DataClass();

  FutureOr<void> buildDeclarationsForClass(ClassDeclaration clazz,
      ClassMemberDeclarationBuilder builder) async {
    Uri dartCore = Uri.parse('dart:core');
    Identifier objectIdentifier =
    await builder.resolveIdentifier(dartCore, 'Object');
    Identifier boolIdentifier =
    await builder.resolveIdentifier(dartCore, 'bool');
    Identifier intIdentifier =
    await builder.resolveIdentifier(dartCore, 'int');
    Identifier stringIdentifier =
    await builder.resolveIdentifier(dartCore, 'String');

    List<FieldDeclaration> fields = await builder.fieldsOf(clazz);
    List<Object> constructorParts = ['const ', clazz.identifier.name, '({'];
    String comma = '';
    for (FieldDeclaration field in fields) {
      constructorParts.addAll([comma, 'required this.', field.identifier]);
      comma = ', ';
    }
    constructorParts.add('});');
    builder.declareInClass(new DeclarationCode.fromParts(constructorParts));

    builder.declareInClass(new DeclarationCode.fromParts([
      'external ', intIdentifier, ' get hashCode;']));
    builder.declareInClass(new DeclarationCode.fromParts([
      'external ',
      boolIdentifier,
      ' operator ==(',
      objectIdentifier,
      ' other);'
    ]));
    builder.declareInClass(new DeclarationCode.fromParts([
      'external ', stringIdentifier, ' toString();']));
  }

  FutureOr<void> buildDefinitionForClass(ClassDeclaration clazz,
      ClassDefinitionBuilder builder) async {
    Uri dartCore = Uri.parse('dart:core');
    Identifier identicalIdentifier =
    await builder.resolveIdentifier(dartCore, 'identical');

    List<FieldDeclaration> fields = await builder.fieldsOf(clazz);
    List<MethodDeclaration> methods = await builder.methodsOf(clazz);

    FunctionDefinitionBuilder hashCodeBuilder = await builder.buildMethod(
        methods
            .firstWhere((e) => e.identifier.name == 'hashCode')
            .identifier);
    FunctionDefinitionBuilder equalsBuilder = await builder.buildMethod(
        methods
            .firstWhere((e) => e.identifier.name == '==')
            .identifier);
    FunctionDefinitionBuilder toStringBuilder = await builder.buildMethod(
        methods
            .firstWhere((e) => e.identifier.name == 'toString')
            .identifier);

    List<Object> hashCodeParts = ['''{
    return '''
    ];

    List<Object> equalsParts = ['''{
    if (''', identicalIdentifier, '''(this, other)) return true;
    return other is ${clazz.identifier.name}'''
    ];

    List<Object> toStringParts = ['''{
    return "${clazz.identifier.name}('''
    ];

    bool first = true;
    for (FieldDeclaration field in fields) {
      if (!first) {
        hashCodeParts.add(' ^ ');
        toStringParts.add(',');
      }
      // TODO(johnniwinther): Generate different code for collection typed
      // fields.
      hashCodeParts.addAll([field.identifier, '.hashCode']);

      equalsParts.addAll(
          [' && ', field.identifier, ' == other.', field.identifier]);

      toStringParts.addAll(
          ['${field.identifier.name}=\${', field.identifier, '}']);

      first = false;
    }

    hashCodeParts.add(''';
  }''');

    equalsParts.add(''';
  }''');

    toStringParts.add(''')";
  }''');

    hashCodeBuilder.augment(new FunctionBodyCode.fromParts(hashCodeParts));
    equalsBuilder.augment(new FunctionBodyCode.fromParts(equalsParts));
    toStringBuilder.augment(new FunctionBodyCode.fromParts(toStringParts));
  }
}
