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

// @dart=2.9

library fasta.tool.entry_points;

import "dart:convert" show JsonEncoder;

import "dart:io" show File;

import "package:kernel/ast.dart";

import "package:front_end/src/fasta/type_inference/type_schema.dart"
    show UnknownType;

String jsonEncode(Object object) {
  return const JsonEncoder.withIndent("  ").convert(object);
}

Iterable<String> nameGenerator() sync* {
  int i = 0;
  while (true) {
    List<int> characters = <int>[];
    int j = i;
    while (j > 25) {
      int c = j % 26;
      j = (j ~/ 26) - 1;
      characters.add(c + 65);
    }
    characters.add(j + 65);
    yield new String.fromCharCodes(characters.reversed);
    i++;
  }
}

class BenchMaker implements DartTypeVisitor1<void, StringBuffer> {
  final List<Object> checks = <Object>[];

  final Map<TreeNode, String> nodeNames = <TreeNode, String>{};

  final Set<String> usedNames = new Set<String>();

  final Iterator<String> names = nameGenerator().iterator..moveNext();

  final List<String> classes = <String>[];

  final List<TypeParameter> usedTypeParameters = <TypeParameter>[];

  String serializeTypeChecks(List<Object> typeChecks) {
    for (List<Object> list in typeChecks) {
      writeTypeCheck(list[0], list[1], list[2]);
    }
    writeClasses();
    return jsonEncode(this);
  }

  void writeTypeCheck(DartType s, DartType t, bool expected) {
    assert(usedTypeParameters.isEmpty);
    usedTypeParameters.clear();
    StringBuffer sb = new StringBuffer();
    s.accept1(this, sb);
    String sString = "$sb";
    sb.clear();
    t.accept1(this, sb);
    String tString = "$sb";
    List<Object> arguments = <Object>[sString, tString];
    Set<TypeParameter> seenTypeParameters = new Set<TypeParameter>();
    List<String> parameterStrings = <String>[];
    while (usedTypeParameters.isNotEmpty) {
      List<TypeParameter> typeParameters = usedTypeParameters.toList();
      usedTypeParameters.clear();
      for (TypeParameter parameter in typeParameters) {
        if (seenTypeParameters.add(parameter)) {
          sb.clear();
          writeTypeParameter(parameter, sb);
          parameterStrings.add("$sb");
        }
      }
    }
    if (parameterStrings.isNotEmpty) {
      arguments.add(parameterStrings);
    }
    checks.add(<String, dynamic>{
      "kind": expected ? "isSubtype" : "isNotSubtype",
      "arguments": arguments,
    });
  }

  void writeTypeParameter(TypeParameter parameter, StringBuffer sb) {
    sb.write(computeName(parameter));
    DartType bound = parameter.bound;
    DartType defaultType = parameter.defaultType;
    bool hasExplicitBound = true;
    if (bound is InterfaceType && defaultType is DynamicType) {
      if (bound.classNode.supertype == null) {
        hasExplicitBound = false;
      }
    }
    if (hasExplicitBound) {
      sb.write(" extends ");
      bound.accept1(this, sb);
    }
  }

  void writeTypeParameters(
      List<TypeParameter> typeParameters, StringBuffer sb) {
    if (typeParameters.isNotEmpty) {
      sb.write("<");
      bool first = true;
      for (TypeParameter p in typeParameters) {
        if (!first) sb.write(", ");
        writeTypeParameter(p, sb);
        first = false;
      }
      sb.write(">");
    }
  }

  void writeClasses() {
    Set<Class> writtenClasses = new Set<Class>();
    int index = 0;
    List<TreeNode> nodes = nodeNames.keys.toList();
    while (index < nodes.length) {
      for (; index < nodes.length; index++) {
        TreeNode node = nodes[index];
        if (node is Class) {
          writeClass(node, writtenClasses);
        }
      }
      nodes = nodeNames.keys.toList();
    }
  }

  void writeClass(Class cls, Set<Class> writtenClasses) {
    if (cls == null || !writtenClasses.add(cls)) return;
    Supertype supertype = cls.supertype;
    writeClass(supertype?.classNode, writtenClasses);
    Supertype mixedInType = cls.mixedInType;
    writeClass(mixedInType?.classNode, writtenClasses);
    for (Supertype implementedType in cls.implementedTypes) {
      writeClass(implementedType.classNode, writtenClasses);
    }
    StringBuffer sb = new StringBuffer();
    sb.write("class ");
    sb.write(computeName(cls));
    writeTypeParameters(cls.typeParameters, sb);
    if (supertype != null) {
      sb.write(" extends ");
      supertype.asInterfaceType.accept1(this, sb);
    }
    if (mixedInType != null) {
      sb.write(" with ");
      mixedInType.asInterfaceType.accept1(this, sb);
    }
    bool first = true;
    for (Supertype implementedType in cls.implementedTypes) {
      if (first) {
        sb.write(" implements ");
      } else {
        sb.write(", ");
      }
      implementedType.asInterfaceType.accept1(this, sb);
      first = false;
    }
    Procedure callOperator;
    for (Procedure procedure in cls.procedures) {
      if (procedure.name.text == "call") {
        callOperator = procedure;
      }
    }
    if (callOperator != null) {
      sb.write("{ ");
      callOperator.function
          .computeFunctionType(cls.enclosingLibrary.nonNullable)
          .accept1(this, sb);
      sb.write(" }");
    } else {
      sb.write(";");
    }
    classes.add("$sb");
  }

  String computeName(TreeNode node) {
    String name = nodeNames[node];
    if (name != null) return name;
    if (node is Class) {
      Library library = node.enclosingLibrary;
      String uriString = "${library?.importUri}";
      if (uriString == "dart:core" || uriString == "dart:async") {
        if (!usedNames.add(node.name)) {
          throw "Class name conflict for $node";
        }
        return nodeNames[node] = node.name;
      }
    }
    while (!usedNames.add(name = names.current)) {
      names.moveNext();
    }
    names.moveNext();
    return nodeNames[node] = name;
  }

  void writeNullability(Nullability nullability, StringBuffer sb) {
    switch (nullability) {
      case Nullability.nullable:
        sb.write("?");
        break;
      case Nullability.legacy:
        sb.write("*");
        break;
      case Nullability.undetermined:
        sb.write("%");
        break;
      case Nullability.nonNullable:
      default:
        break;
    }
  }

  @override
  void defaultDartType(DartType node, StringBuffer sb) {
    if (node is UnknownType) {
      sb.write("?");
    } else {
      throw "Unsupported: ${node.runtimeType}";
    }
  }

  @override
  void visitInvalidType(InvalidType node, StringBuffer sb) {
    throw "not implemented";
  }

  @override
  void visitDynamicType(DynamicType node, StringBuffer sb) {
    sb.write("dynamic");
  }

  @override
  void visitVoidType(VoidType node, StringBuffer sb) {
    sb.write("void");
  }

  @override
  void visitNeverType(NeverType node, StringBuffer sb) {
    sb.write("Never");
    writeNullability(node.nullability, sb);
  }

  @override
  void visitNullType(NullType node, StringBuffer sb) {
    sb.write("Null");
  }

  @override
  void visitInterfaceType(InterfaceType node, StringBuffer sb) {
    Class cls = node.classNode;
    sb.write(computeName(cls));
    if (node.typeArguments.isNotEmpty) {
      sb.write("<");
      bool first = true;
      for (DartType type in node.typeArguments) {
        if (!first) sb.write(", ");
        type.accept1(this, sb);
        first = false;
      }
      sb.write(">");
    }
    Uri clsImportUri = cls.enclosingLibrary.importUri;
    bool isNull = cls.name == "Null" &&
        clsImportUri.scheme == "dart" &&
        clsImportUri.path == "core";
    if (!isNull) {
      writeNullability(node.nullability, sb);
    }
  }

  @override
  void visitFutureOrType(FutureOrType node, StringBuffer sb) {
    sb.write("FutureOr<");
    node.typeArgument.accept1(this, sb);
    sb.write(">");
    writeNullability(node.declaredNullability, sb);
  }

  @override
  void visitFunctionType(FunctionType node, StringBuffer sb) {
    writeTypeParameters(node.typeParameters, sb);
    sb.write("(");
    bool first = true;
    for (int i = 0; i < node.requiredParameterCount; i++) {
      if (!first) sb.write(", ");
      node.positionalParameters[i].accept1(this, sb);
      first = false;
    }
    if (node.requiredParameterCount != node.positionalParameters.length) {
      if (!first) sb.write(", ");
      sb.write("[");
      first = true;
      for (int i = node.requiredParameterCount;
          i < node.positionalParameters.length;
          i++) {
        if (!first) sb.write(", ");
        node.positionalParameters[i].accept1(this, sb);
        first = false;
      }
      sb.write("]");
      first = false;
    }
    if (node.namedParameters.isNotEmpty) {
      if (!first) sb.write(", ");
      sb.write("{");
      first = true;
      for (NamedType named in node.namedParameters) {
        if (!first) sb.write(", ");
        named.type.accept1(this, sb);
        sb.write(" ");
        sb.write(named.name);
        first = false;
      }
      sb.write("}");
      first = false;
    }
    sb.write(") ->");
    writeNullability(node.nullability, sb);
    sb.write(" ");
    node.returnType.accept1(this, sb);
  }

  @override
  void visitTypeParameterType(TypeParameterType node, StringBuffer sb) {
    String name = computeName(node.parameter);
    usedTypeParameters.add(node.parameter);
    sb.write(name);
    if (node.promotedBound != null) {
      sb.write(" & ");
      node.promotedBound.accept1(this, sb);
    }
  }

  @override
  void visitTypedefType(TypedefType node, StringBuffer sb) {
    throw "not implemented";
  }

  @override
  void visitExtensionType(ExtensionType node, StringBuffer sb) {
    throw "not implemented";
  }

  Map<String, dynamic> toJson() {
    return <String, dynamic>{
      "classes": classes,
      "checks": checks,
    };
  }

  static void writeTypeChecks(String filename, List<Object> typeChecks) {
    new File(filename)
        .writeAsString(new BenchMaker().serializeTypeChecks(typeChecks));
  }
}
