// 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.

/// This tool builds a program with a deferred graph isomorphic to the provided
/// graph, or generates permutations of bits and the associated files to
/// generate complex deferred graphs.
///
/// For example, if 5 bits are permuted, we end up with files like:
///   lib1.dart
///   lib2.dart
///   lib3.dart
///   lib4.dart
///   lib5.dart
///   libB.dart
///   lib_000_01.dart
///   lib_000_10.dart
///   lib_001_00.dart
///   lib_010_00.dart
///   lib_100_00.dart
///   main.dart
///
/// Where
///   main.dart contains main().
///   libX.dart contains the actual deferred import of the file with the bit at
///     the X position starting from the left, ie lib1 imports lib_100_00, lib2
///     imports lib_010_00, etc.
///   libImport.dart is the 'top of the diamond' which contains all of the code.
///   lib_XXX_XX.dart invokes all of the functions in libImport which have a
///     1 bit at that position, ie lib_100_00 invokes all code in libImport with
///     a first bit of 1, f100_00, f110_00, etc.
///
/// Note: There are restrictions to what we can generate. Specifically, certain
/// OutputUnits can never be empty, namely we will always generate one file for
/// each entryLib, and because of our dependency on expect, we will always have
/// a file representing the intersection of all import entities. So, for example
/// with three bits, each of 100, 010, 001 and 111 must be present in the graph
/// file, but 110, 101, and 011 are optional.
library;

// TODO(joshualitt): This is a good start for a fuzzer. There is still work to
// do:
// * Emit some classes as const and some not
// * Randomize what we emit as we walk the graph so it is more sparse.

import 'dart:io';
import 'dart:math';
import 'package:dart_style/dart_style.dart' show DartFormatter;

typedef NameFunc = String Function(List<int>, int);

/// A simple constant pass through function for bit strings that don't need
/// special printing, ie stops.
String passThroughNameFunc(List<int> l, int i) => l[i].toString();

/// Generates all permutations of bits recursively.
void generatePermutedNames(
  Map<int, List<List<int>>> names,
  int maxBit,
  List<int> bits,
  int bit,
) {
  if (bit == maxBit) {
    for (int i = 0; i < bits.length; i++) {
      if (bits[i] == 1) {
        names.putIfAbsent(i, () => []);
        names[i]!.add(List.from(bits));
      }
    }
    return;
  }
  generatePermutedNames(names, maxBit, bits, bit + 1);
  bits[bit] = 1;
  generatePermutedNames(names, maxBit, bits, bit + 1);
  bits[bit] = 0;
}

/// A helper function to generate names from lists of strings of bits.
int namesFromGraphFileLines(
  List<String> lines,
  Map<int, List<List<int>>> names,
) {
  int maxBit = 0;
  for (var line in lines) {
    List<int> name = [];
    // Each line should have the same length.
    assert(maxBit == 0 || maxBit == line.length);
    maxBit = max(maxBit, line.length);
    for (int i = 0; i < line.length; i++) {
      var bit = line[i];
      if (bit == '1') {
        name.add(1);
        (names[i] ??= []).add(name);
      } else {
        name.add(0);
      }
    }
  }
  return maxBit;
}

/// Parses names from a graph file dumped from dart2js and returns the max bit.
int namesFromGraphFile(String graphFile, Map<int, List<List<int>>> names) {
  var lines = File(graphFile).readAsLinesSync();
  return namesFromGraphFileLines(lines, names);
}

class ImportData {
  String import;
  String entryPoint;

  ImportData(this.import, this.entryPoint);
}

class GraphIsomorphizer {
  /// The output directory, only relevant if files are written out.
  final String outDirectory;

  /// Various buffers for the files the GraphIsomorphizer generates.
  StringBuffer rootImportBuffer = StringBuffer();
  StringBuffer mainBuffer = StringBuffer();
  Map<String, StringBuffer> mixerLibBuffers = {};
  Map<String, StringBuffer> entryLibBuffers = {};

  /// A map of bit positions to lists of bit lists.
  final Map<int, List<List<int>>> names;

  /// A map of bit positions to lists of class names.
  final Map<int, List<String>> classNames = {};
  final Map<int, List<String>> mixerClassNames = {};

  /// A map of bit positions to lists of mixin names.
  final Map<int, List<String>> mixinNames = {};

  /// A map of bit positions to lists of class names used only as types.
  final Map<int, List<String>> typeNames = {};
  final Map<int, List<String>> mixerTypeNames = {};
  final Map<int, List<String>> closureNames = {};

  /// We will permute bits up until the maximum bit.
  int maxBit = 0;

  /// The 'top of the diamond' import file containing all code.
  final String rootImportFilename = 'libImport.dart';

  /// The main filename.
  final String mainFilename = 'main.dart';

  /// A bool to omit the comment block.
  final bool skipCopyright;

  // A bool to generate simple code within test files.
  final bool simple;

  GraphIsomorphizer(
    this.names,
    this.maxBit, {
    this.outDirectory = '.',
    this.skipCopyright = false,
    this.simple = false,
  });

  void noInlineDecorator(StringBuffer out) {
    out.write("@pragma('dart2js:noInline')\n");
  }

  void importExpect(StringBuffer out) {
    out.write('import "package:expect/expect.dart";\n\n');
  }

  void newline(StringBuffer out) {
    out.write('\n');
  }

  /// Generates the header for a file.
  void generateHeader(StringBuffer out) {
    if (!skipCopyright) {
      out.write("""
// 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.

// This file was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
""");
    }
  }

  /// Generates the root import, where classes, types, mixins, and closures
  /// live.
  void generateRootImport(StringBuffer out) {
    generateHeader(out);
    importExpect(out);

    // We verify that each function in libImport is invoked only once from each
    // mixerLib and that only the correct functions are called, ie for lib_001,
    // only functions with XX1 are invoked.
    out.write(
      'void v(Set<String> u, String name, int bit) {\n'
      '  Expect.isTrue(u.add(name));\n'
      "  Expect.equals(name[bit], '1');\n"
      '}\n\n',
    );

    // Sort the names to ensure they are in a canonical order.
    var nameKeys = names.keys.toList();
    nameKeys.sort();

    Set<String> uniques = {};
    if (!simple) {
      // Generate the 'base' classes, mixins, and types which will be combined to
      // generate hierarchies. Also generate a const instance per class and a closure
      // to invoke.
      for (var bitPosition in nameKeys) {
        var bitsList = names[bitPosition]!;
        for (var bits in bitsList) {
          var name = generateBitString(bits);
          if (!uniques.add(name)) continue;
          String className = 'C$name';
          String mixinName = 'M$name';
          String typeName = 'T$name';
          (classNames[bitPosition] ??= []).add(className);
          (mixinNames[bitPosition] ??= []).add(mixinName);
          (typeNames[bitPosition] ??= []).add(typeName);
          (mixerClassNames[bitPosition] ??= []).add(className);
          (mixerTypeNames[bitPosition] ??= []).add(typeName);
          out.write('class $className { const $className(); }\n');
          out.write('mixin $mixinName {}\n');
          out.write('class $typeName {}\n');
          out.write('const $className i$className = const $className();\n');
          out.write('closure$className(foo) => ($className unused) ');
          out.write('=> i$className.toString() == foo.toString();\n');
        }
      }

      // Generate combined classes and types, as well as const instances and
      // closures.
      newline(out);
      uniques = {};
      for (var bitPosition in nameKeys) {
        var bitsList = names[bitPosition]!;
        for (var bits in bitsList) {
          var name = generateBitString(bits);
          var bitCount = bits.reduce((a, b) => a + b);
          var baseName = 'C$name';
          if (!uniques.add(baseName)) continue;
          if (bitCount > 1) {
            List<String> classes = [];
            List<String> mixins = [];
            List<String> types = [];
            for (int i = 0; i < bits.length; i++) {
              if (bits[i] == 1) {
                classes.addAll(classNames[i]!);
                mixins.addAll(mixinNames[i]!);
                types.addAll(typeNames[i]!);
              }
            }
            String mixinString = mixins.join(', ');
            int count = 1;
            assert(classes.length == types.length);
            for (int i = 0; i < classes.length; i++) {
              var cls = classes[i];
              var type = types[i];
              List<String> classImpls = [];
              List<String> typeImpls = [];
              if (i > 0) {
                classImpls.addAll(classes.sublist(0, i));
                typeImpls.addAll(types.sublist(0, i));
              }
              if (i < classes.length - 1) {
                classImpls.addAll(classes.sublist(i + 1));
                typeImpls.addAll(types.sublist(i + 1));
              }
              var classImplementsString = classImpls.join(', ');
              String className = '${baseName}_class_$count';
              out.write('class $className extends $cls with $mixinString ');
              out.write(
                'implements $classImplementsString { const $className(); }\n',
              );
              out.write('const $className i$className = const $className();\n');
              out.write('closure$className(foo) => ($className unused) ');
              out.write('=> i$className.toString() == foo.toString();\n');

              var typeImplementsString = typeImpls.join(', ');
              String typeName = 'T${name}_type__$count';
              out.write('class $typeName extends $type with $mixinString ');
              out.write('implements $typeImplementsString {}\n');
              for (int i = 0; i < bits.length; i++) {
                if (bits[i] == 1) {
                  mixerClassNames[i]!.add(className);
                  mixerTypeNames[i]!.add(typeName);
                }
              }
              count++;
            }
          }
        }
      }
    }

    // Generate functions.
    newline(out);
    uniques = {};
    for (var name in nameKeys) {
      var bitsList = names[name]!;
      for (var bits in bitsList) {
        var name = generateBitString(bits);
        if (uniques.add(name)) {
          noInlineDecorator(out);
          var stringBits = generateBitString(bits, withStops: false);
          out.write(
            "f$name(Set<String> u, int b) => v(u, '$stringBits', b);\n",
          );
        }
      }
    }
  }

  /// Generates a mixerLib which will be loaded as a deferred library from an entryLib.
  void generateMixerLib(
    String name,
    StringBuffer out,
    String import,
    List<int> bits,
    int bit,
  ) {
    generateHeader(out);
    importExpect(out);
    out.write("import '$import';\n\n");

    if (!simple) {
      // create type test.
      noInlineDecorator(out);
      out.write('typeTest(dynamic t) {\n');
      for (var type in mixerTypeNames[bit]!) {
        out.write('  if (t is $type) { return true; }\n');
      }
      out.write('  return false;\n');
      out.write('}\n\n');
    }

    noInlineDecorator(out);
    out.write('g$name() {\n');

    if (!simple) {
      out.write('  // C${generateCommentName(bits, bit)};\n');

      // Construct new instances of each class and pass them to the typeTest
      for (var cls in mixerClassNames[bit]!) {
        out.write('  Expect.isFalse(typeTest($cls()));\n');
      }
      newline(out);

      // Invoke the test closure for each class.
      for (var cls in mixerClassNames[bit]!) {
        out.write('  Expect.isTrue(closure$cls($cls())($cls()));\n');
      }
      newline(out);

      // Verify the runtimeTypes of the closures haven't been mangled.
      for (var cls in mixerClassNames[bit]!) {
        out.write(
          '  Expect.equals(closure$cls($cls()).runtimeType.toString(), ',
        );
        out.write("'($cls) => bool');\n");
      }
    }
    newline(out);

    // Collect the names so we can sort them and put them in a canonical order.
    int count = 0;
    List<String> namesBits = [];
    for (var nameBits in names[bit]!) {
      var nameString = generateBitString(nameBits);
      namesBits.add(nameString);
      count++;
    }

    out.write(
      '  Set<String> uniques = {};\n\n'
      '  // f${generateCommentName(bits, bit)};\n',
    );

    namesBits.sort();
    for (var name in namesBits) {
      out.write('  f$name(uniques, $bit);\n');
    }

    // We expect 'count' unique strings added to be added to 'uniques'.
    out.write(
      "  Expect.equals($count, uniques.length);\n"
      '}\n',
    );
  }

  /// Generates a string of bits, with optional parameters to control how the
  /// bits print.
  String generateBitString(
    List<int> bits, {
    NameFunc f = passThroughNameFunc,
    bool withStops = true,
  }) {
    int stop = 0;
    StringBuffer sb = StringBuffer();
    for (int i = 0; i < bits.length; i++) {
      if (stop++ % 3 == 0 && withStops) {
        sb.write('_');
      }
      sb.write(f(bits, i));
    }
    return sb.toString();
  }

  /// Generates a pretty bit string for use in comments.
  String generateCommentName(List<int> bits, int fixBit) {
    return generateBitString(
      bits,
      f: (List<int> bits, int bit) => bit == fixBit ? '1' : '*',
    );
  }

  /// Generates an entryLib file.
  void generateEntryLib(
    StringBuffer out,
    String mainName,
    String funcName,
    String import,
    int bit,
  ) {
    generateHeader(out);
    var name = 'b$bit';
    out.write(
      "import '$import' deferred as $name;\n\n"
      '$mainName async {\n'
      '  await $name.loadLibrary();\n'
      '  $name.g$funcName();\n'
      '}\n',
    );
  }

  /// Generates entry and mixer libs for the supplied names.
  List<ImportData> generateEntryAndMixerLibs() {
    // Generates each lib_XXX.dart and the associated entryLib file.
    List<ImportData> importData = [];
    for (int i = 1; i <= maxBit; i++) {
      // Generate the bit list representing this library. ie a list of all
      // 0s with a single 1 bit flipped.
      int oneBit = i - 1;
      List<int> bits = [];
      for (int j = 0; j < maxBit; j++) {
        bits.add(j == oneBit ? 1 : 0);
      }

      // Generate the mixerLib for this entryLib.
      var name = generateBitString(bits);
      var mixerLibBuffer = StringBuffer();
      var mixerLibName = "lib$name.dart";
      generateMixerLib(name, mixerLibBuffer, rootImportFilename, bits, oneBit);
      mixerLibBuffers[mixerLibName] = mixerLibBuffer;

      // Generate the entryLib for this mixerLib.
      var entryLibName = 'lib$i.dart';
      var entryFuncName = 'entryLib$i()';
      var entryLibBuffer = StringBuffer();
      generateEntryLib(entryLibBuffer, entryFuncName, name, mixerLibName, i);
      entryLibBuffers[entryLibName] = entryLibBuffer;

      // Stash the entry point in entryLib for later reference in the main file.
      importData.add(ImportData(entryLibName, entryFuncName));
    }
    return importData;
  }

  /// Generates the main file.
  void generateMain(StringBuffer out, List<ImportData> importData) {
    generateHeader(mainBuffer);
    for (var data in importData) {
      out.write("import '${data.import}';\n");
    }
    out.write(
      '\n'
      'main() {\n',
    );
    for (var data in importData) {
      out.write('  ${data.entryPoint};\n');
    }
    out.write('}\n');
  }

  /// Generates all files into buffers.
  void generateFiles() {
    generateRootImport(rootImportBuffer);
    var importData = generateEntryAndMixerLibs();
    generateMain(mainBuffer, importData);
  }

  /// Helper to dump contents to file.
  void writeToFile(String filename, StringBuffer contents) {
    var file = File('$outDirectory/$filename');
    file.createSync(recursive: true);
    var sink = file.openWrite();
    sink.write(
      DartFormatter(
        languageVersion: DartFormatter.latestLanguageVersion,
      ).format(contents.toString()),
    );
    sink.close();
  }

  /// Writes all buffers to files.
  void writeFiles() {
    mixerLibBuffers.forEach(writeToFile);
    entryLibBuffers.forEach(writeToFile);
    writeToFile(rootImportFilename, rootImportBuffer);
    writeToFile(mainFilename, mainBuffer);
  }

  /// Generate and write files.
  void run() {
    generateFiles();
    writeFiles();
  }
}

/// Creates a GraphIsomorphizer based on the provided args.
GraphIsomorphizer createGraphIsomorphizer(List<String> args) {
  bool simple = true;
  int maxBit = 0;
  String graphFile = '';
  String outDirectory = '.';

  for (var arg in args) {
    if (arg.startsWith('--max-bit')) {
      maxBit = int.parse(arg.substring('--max-bit='.length));
    }
    if (arg.startsWith('--graph-file')) {
      graphFile = arg.substring('--graph-file='.length);
    }
    if (arg.startsWith('--out-dir')) {
      outDirectory = arg.substring('--out-dir='.length);
    }
    if (arg == '--simple') {
      simple = true;
    }
  }

  // If we don't have a graphFile, then we generate all permutations of bits up
  // to maxBit.
  Map<int, List<List<int>>> names = {};
  if (graphFile.isEmpty) {
    List<int> bits = List.filled(maxBit, 0);
    generatePermutedNames(names, maxBit, bits, 0);
  } else {
    maxBit = namesFromGraphFile(graphFile, names);
  }
  return GraphIsomorphizer(
    names,
    maxBit,
    outDirectory: outDirectory,
    simple: simple,
  );
}

void main(List<String> args) {
  var graphIsomorphizer = createGraphIsomorphizer(args);
  graphIsomorphizer.run();
}
