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

// Generates the API tables used by DartFuzz. Automatically generating these
// tables is less error-prone than generating such tables by hand. Furthermore,
// it simplifies regenerating the table when the libraries change.
//
// Usage:
//   dart gen_api_table.dart > dartfuzz_api_table.dart
//
// Then send out modified dartfuzz_api_table.dart for review together
// with a modified dartfuzz.dart that increases the version.

import 'dart:io';

import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/file_system/physical_file_system.dart';

import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';

// Class to represent a library method by name and prototype representation.
class DartLib {
  final String name;
  final String proto;
  const DartLib(this.name, this.proto);
}

// Lists of recognized methods, organized by return type.
var boolTable = <DartLib>[];
var intTable = <DartLib>[];
var doubleTable = <DartLib>[];
var stringTable = <DartLib>[];
var listTable = <DartLib>[];
var setTable = <DartLib>[];
var mapTable = <DartLib>[];

main() async {
  // Set paths. Note that for this particular use case, packageRoot can be
  // any directory. Here, we set it to the top of the SDK development, and
  // derive the required sdkPath from there.
  final String packageRoot = Platform.environment['DART_TOP'];
  if (packageRoot == null) {
    throw StateError('No environment variable DART_TOP');
  }
  final sdkPath = '$packageRoot/tools/sdks/dart-sdk';

  // This does most of the hard work of getting the analyzer configured
  // correctly. Typically the included paths are the files and directories
  // that need to be analyzed, but the SDK is always available, so it isn't
  // really important for this particular use case. We use the implementation
  // class in order to pass in the sdkPath directly.
  final provider = PhysicalResourceProvider.INSTANCE;
  final collection = AnalysisContextCollectionImpl(
      includedPaths: <String>[packageRoot],
      excludedPaths: <String>[packageRoot + "/pkg/front_end/test"],
      resourceProvider: provider,
      sdkPath: sdkPath);
  final AnalysisSession session = collection.contexts[0].currentSession;

  // Visit libraries for table generation.
  await visitLibraryAtUri(session, 'dart:async');
  await visitLibraryAtUri(session, 'dart:cli');
  await visitLibraryAtUri(session, 'dart:collection');
  await visitLibraryAtUri(session, 'dart:convert');
  await visitLibraryAtUri(session, 'dart:core');
  await visitLibraryAtUri(session, 'dart:io');
  await visitLibraryAtUri(session, 'dart:isolate');
  await visitLibraryAtUri(session, 'dart:math');
  await visitLibraryAtUri(session, 'dart:typed_data');

  // Generate the tables in a stand-alone Dart class.
  dumpHeader();
  dumpTable('boolLibs', boolTable);
  dumpTable('intLibs', intTable);
  dumpTable('doubleLibs', doubleTable);
  dumpTable('stringLibs', stringTable);
  dumpTable('listLibs', listTable);
  dumpTable('setLibs', setTable);
  dumpTable('mapLibs', mapTable);
  dumpFooter();
}

visitLibraryAtUri(AnalysisSession session, String uri) async {
  final String libPath = session.uriConverter.uriToPath(Uri.parse(uri));
  ResolvedLibraryResult result = await session.getResolvedLibrary(libPath);
  if (result.state != ResultState.VALID) {
    throw StateError('Unable to resolve "$uri"');
  }
  visitLibrary(result.element);
}

visitLibrary(LibraryElement library) async {
  // This uses the element model to traverse the code. The element model
  // represents the semantic structure of the code. A library consists of
  // one or more compilation units.
  for (CompilationUnitElement unit in library.units) {
    visitCompilationUnit(unit);
  }
}

visitCompilationUnit(CompilationUnitElement unit) {
  // Each compilation unit contains elements for all of the top-level
  // declarations in a single file, such as variables, functions, and
  // classes. Note that `types` only returns classes. You can use
  // `mixins` to visit mixins, `enums` to visit enum, `functionTypeAliases`
  // to visit typedefs, etc.
  for (TopLevelVariableElement variable in unit.topLevelVariables) {
    if (variable.isPublic) {
      addToTable(typeString(variable.type), variable.name, 'Vv');
    }
  }
  for (FunctionElement function in unit.functions) {
    if (function.isPublic && !function.isOperator) {
      addToTable(typeString(function.returnType), function.name,
          protoString(null, function.parameters));
    }
  }
  for (ClassElement classElement in unit.types) {
    if (classElement.isPublic) {
      visitClass(classElement);
    }
  }
}

void visitClass(ClassElement classElement) {
  // Classes that cause too many false divergences.
  if (classElement.name == 'ProcessInfo' ||
      classElement.name == 'Platform' ||
      classElement.name.startsWith('FileSystem')) {
    return;
  }
  // Every class element contains elements for the members, viz. `methods` visits
  // methods, `fields` visits fields, `accessors` visits getters and setters, etc.
  // There are also accessors to get the superclass, mixins, interfaces, type
  // parameters, etc.
  for (ConstructorElement constructor in classElement.constructors) {
    if (constructor.isPublic &&
        constructor.isFactory &&
        constructor.name.isNotEmpty) {
      addToTable(
          typeString(classElement.type),
          '${classElement.name}.${constructor.name}',
          protoString(null, constructor.parameters));
    }
  }
  for (MethodElement method in classElement.methods) {
    if (method.isPublic && !method.isOperator) {
      if (method.isStatic) {
        addToTable(
            typeString(method.returnType),
            '${classElement.name}.${method.name}',
            protoString(null, method.parameters));
      } else {
        addToTable(typeString(method.returnType), method.name,
            protoString(classElement.type, method.parameters));
      }
    }
  }
  for (PropertyAccessorElement accessor in classElement.accessors) {
    if (accessor.isPublic && accessor.isGetter) {
      var variable = accessor.variable;
      if (accessor.isStatic) {
        addToTable(typeString(variable.type),
            '${classElement.name}.${variable.name}', 'Vv');
      } else {
        addToTable(typeString(variable.type), variable.name,
            '${typeString(classElement.type)}v');
      }
    }
  }
}

// Types are represented by an instance of `DartType`. For classes, the type
// will be an instance of `InterfaceType`, which will provide access to the
// defining (class) element, as well as any type arguments.
String typeString(DartType type) {
  if (type.isDartCoreBool) {
    return 'B';
  } else if (type.isDartCoreInt) {
    return 'I';
  } else if (type.isDartCoreDouble) {
    return 'D';
  } else if (type.isDartCoreString) {
    return 'S';
  }
  // Supertypes or type parameters are specialized in a consistent manner.
  // TODO(ajcbik): inspect type structure semantically, not by display name
  //               and unify DartFuzz's DartType with analyzer DartType.
  switch (type.displayName) {
    case 'E':
      return 'I';
    case 'num':
      return 'D';
    case 'List<E>':
    case 'List<Object>':
    case 'List<dynamic>':
    case 'List<int>':
    case 'List':
      return 'L';
    case 'Set<E>':
    case 'Set<Object>':
    case 'Set<dynamic>':
    case 'Set<int>':
    case 'Set':
      return 'X';
    case 'Map<K, V>':
    case 'Map<dynamic, dynamic>':
    case 'Map<int, String>':
    case 'Map':
      return 'M';
  }
  return '?';
}

String protoString(DartType receiver, List<ParameterElement> parameters) {
  var proto = receiver == null ? 'V' : typeString(receiver);
  // Construct prototype for non-named parameters.
  for (ParameterElement parameter in parameters) {
    if (!parameter.isNamed) {
      proto += typeString(parameter.type);
    }
  }
  // Use 'void' for an empty parameter list.
  return proto.length == 1 ? proto + 'V' : proto;
}

List<DartLib> getTable(String ret) {
  switch (ret) {
    case 'B':
      return boolTable;
    case 'I':
      return intTable;
    case 'D':
      return doubleTable;
    case 'S':
      return stringTable;
    case 'L':
      return listTable;
    case 'X':
      return setTable;
    case 'M':
      return mapTable;
    default:
      throw ArgumentError('Invalid ret value: $ret');
  }
}

void addToTable(String ret, String name, String proto) {
  // If any of the type representations contains a question
  // mark, this means that DartFuzz' type system cannot
  // deal with such an expression yet. So drop the entry.
  if (ret.contains('?') || proto.contains('?')) {
    return;
  }
  // Avoid some obvious false divergences.
  if (name == 'pid' || name == 'hashCode' || name == 'exitCode') {
    return;
  }
  // Restrict parameters for a few hardcoded cases,
  // for example, to avoid excessive runtime or memory
  // allocation in the generated fuzzing program.
  if (name == 'padLeft' || name == 'padRight') {
    proto = proto.replaceFirst('IS', 'is');
  } else if (name == 'List.filled') {
    proto = proto.replaceFirst('I', 'i');
  }
  // Add to table.
  getTable(ret).add(DartLib(name, proto));
}

void dumpHeader() {
  print("""
// 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.

/// Class that represents Dart library methods.
///
/// The invididual lists are organized by return type.
/// The proto string has the following format:
///    +-------> receiver type (V denotes none)
///    |+------> param1 type  (V denotes none, v denotes getter)
///    ||+-----> param2 type
///    |||+----> ..
///    ||||
///   'TTTT..'
/// where:
///   V void
///   v void (special)
///   B bool
///   I int
///   i int (small)
///   D double
///   S String
///   s String (small)
///   L List<int>
///   X Set<int>
///   M Map<int, String>
///
/// NOTE: this code has been generated automatically.
///
class DartLib {
  final String name;
  final String proto;
  const DartLib(this.name, this.proto);
""");
}

void dumpTable(String identifier, List<DartLib> table) {
  print('  static const $identifier = [');
  table.forEach((t) => print('    DartLib(\'${t.name}\', \'${t.proto}\'),'));
  print('  ];');
}

void dumpFooter() {
  print('}');
}
