// Copyright (c) 2014, 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.

/// Code generation for the file "matchers.dart".
library;

import 'package:analyzer_utilities/tools.dart';

import 'api.dart';
import 'from_html.dart';
import 'implied_types.dart';
import 'to_html.dart';

final GeneratedFile target = GeneratedFile(
  'analyzer_plugin/test/integration/support/protocol_matchers.dart',
  (pkgRoot) async {
    var visitor = CodegenMatchersVisitor(readApi(pkgRoot));
    return visitor.collectCode(visitor.visitApi);
  },
);

class CodegenMatchersVisitor extends HierarchicalApiVisitor with CodeGenerator {
  /// Visitor used to produce doc comments.
  final ToHtmlVisitor toHtmlVisitor;

  /// Short human-readable string describing the context of the matcher being
  /// created.
  String? context;

  CodegenMatchersVisitor(super.api) : toHtmlVisitor = ToHtmlVisitor(api) {
    codeGeneratorSettings.commentLineLength = 79;
    codeGeneratorSettings.docCommentStartMarker = null;
    codeGeneratorSettings.docCommentLineLeader = '/// ';
    codeGeneratorSettings.docCommentEndMarker = null;
    codeGeneratorSettings.languageName = 'dart';
  }

  /// Create a matcher for the part of the API called [name], optionally
  /// clarified by [nameSuffix]. The matcher should verify that its input
  /// matches the given [type].
  void makeMatcher(ImpliedType impliedType) {
    context = impliedType.humanReadableName;
    docComment(
      toHtmlVisitor.collectHtml(() {
        toHtmlVisitor.p(() {
          toHtmlVisitor.write(context!);
        });
        var type = impliedType.type;
        if (type != null) {
          toHtmlVisitor.showType(null, type);
        }
      }),
    );
    write('final Matcher ${camelJoin(['is', impliedType.camelName])} = ');
    var type = impliedType.type;
    if (type == null) {
      write('isNull');
    } else {
      visitTypeDecl(type);
    }
    writeln(';');
    writeln();
  }

  /// Generate a map describing the given set of fields, for use as the
  /// 'requiredFields' or 'optionalFields' argument to the [MatchesJsonObject]
  /// constructor.
  void outputObjectFields(Iterable<TypeObjectField> fields) {
    if (fields.isEmpty) {
      write('null');
      return;
    }
    writeln('{');
    indent(() {
      var commaNeeded = false;
      for (var field in fields) {
        if (commaNeeded) {
          writeln(',');
        }
        write("'${field.name}': ");
        if (field.value != null) {
          write("equals('${field.value}')");
        } else {
          visitTypeDecl(field.type);
        }
        commaNeeded = true;
      }
      writeln();
    });
    write('}');
  }

  @override
  void visitApi() {
    outputHeader(year: '2017');
    writeln();
    writeln('/// Matchers for data types defined in the analysis server API.');
    writeln('library;');
    writeln();
    writeln("import 'package:test/test.dart';");
    writeln();
    writeln("import 'integration_tests.dart';");
    writeln();
    writeln('// ignore_for_file: flutter_style_todos');
    writeln();
    var impliedTypes = computeImpliedTypes(api).values.toList();
    impliedTypes.sort(
      (ImpliedType first, ImpliedType second) =>
          first.camelName.compareTo(second.camelName),
    );
    for (var impliedType in impliedTypes) {
      makeMatcher(impliedType);
    }
  }

  @override
  void visitTypeEnum(TypeEnum typeEnum) {
    writeln("MatchesEnum('$context', [");
    indent(() {
      var commaNeeded = false;
      for (var value in typeEnum.values) {
        if (commaNeeded) {
          writeln(',');
        }
        write("'${value.value}'");
        commaNeeded = true;
      }
      writeln();
    });
    write('])');
  }

  @override
  void visitTypeList(TypeList typeList) {
    write('isListOf(');
    visitTypeDecl(typeList.itemType);
    write(')');
  }

  @override
  void visitTypeMap(TypeMap typeMap) {
    write('isMapOf(');
    visitTypeDecl(typeMap.keyType);
    write(', ');
    visitTypeDecl(typeMap.valueType);
    write(')');
  }

  @override
  void visitTypeObject(TypeObject typeObject) {
    writeln('LazyMatcher(() => MatchesJsonObject(');
    indent(() {
      write("'$context', ");
      var requiredFields = typeObject.fields.where(
        (TypeObjectField field) => !field.optional,
      );
      outputObjectFields(requiredFields);
      var optionalFields = typeObject.fields
          .where((TypeObjectField field) => field.optional)
          .toList();
      if (optionalFields.isNotEmpty) {
        write(', optionalFields: ');
        outputObjectFields(optionalFields);
      }
    });
    write('))');
  }

  @override
  void visitTypeReference(TypeReference typeReference) {
    var typeName = typeReference.typeName;
    if (typeName == 'long') {
      typeName = 'int';
    }
    write(camelJoin(['is', typeName]));
  }

  @override
  void visitTypeUnion(TypeUnion typeUnion) {
    var commaNeeded = false;
    write('isOneOf([');
    for (var choice in typeUnion.choices) {
      if (commaNeeded) {
        write(', ');
      }
      visitTypeDecl(choice);
      commaNeeded = true;
    }
    write('])');
  }
}
