#!/usr/bin/env dart
// Copyright (c) 2015, 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.

/// Command line tool to merge the SDK libraries and our patch files.
/// This is currently designed as an offline tool, but we could automate it.

import 'dart:io';

import 'package:_fe_analyzer_shared/src/util/relativize.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:args/args.dart';
import 'package:front_end/src/base/libraries_specification.dart';
import 'package:front_end/src/fasta/resolve_input_uri.dart';
import 'package:pub_semver/pub_semver.dart';

void main(List<String> argv) {
  var args = _parser.parse(argv);
  if (args['libraries'] == null || args['out'] == null) {
    var self = relativizeUri(Uri.base, Platform.script, isWindows);
    var librariesJson = relativizeUri(Uri.base,
        Platform.script.resolve('../../../sdk/lib/libraries.json'), isWindows);
    print('Usage: $self [other options]'
        ' --libraries <libraries.json> --out <output-dir>');
    print('For example:');
    print('\$ $self --nnbd --libraries $librariesJson --out patched-sdk-dir');
    exit(1);
  }

  var useNnbd = args['nnbd'] as bool;
  var target = args['target'] as String;
  var jsonUri = resolveInputUri(args['libraries'] as String);
  var libRoot = jsonUri.resolve('./');
  var outPath = args['out'] as String;
  var outDir = resolveInputUri(outPath.endsWith('/') ? outPath : '$outPath/');
  var outLibRoot = outDir.resolve('lib/');

  var inputVersion = Uri.file(Platform.executable).resolve('../version');
  var outVersion = outDir.resolve('version');

  var specification = LibrariesSpecification.parse(
          jsonUri, File.fromUri(jsonUri).readAsStringSync())
      .specificationFor(target);

  // Copy libraries.dart and version
  _writeSync(outVersion, File.fromUri(inputVersion).readAsStringSync());

  // Enumerate sdk libraries and apply patches
  for (var library in specification.allLibraries) {
    var libraryFile = File.fromUri(library.uri);
    var libraryOut =
        outLibRoot.resolve(relativizeLibraryUri(libRoot, library.uri, useNnbd));
    if (libraryFile.existsSync()) {
      var outUris = <Uri>[libraryOut];
      var libraryContents = libraryFile.readAsStringSync();
      var contents = <String>[libraryContents];

      for (var part
          in _parseString(libraryContents, useNnbd: useNnbd).unit.directives) {
        if (part is PartDirective) {
          var partPath = part.uri.stringValue;
          outUris.add(libraryOut.resolve(partPath));
          contents.add(
              File.fromUri(library.uri.resolve(partPath)).readAsStringSync());
        }
      }

      if (args['merge-parts'] as bool && outUris.length > 1) {
        outUris.length = 1;
        contents = [
          contents
              .join('\n')
              .replaceAll(RegExp('^part [^\n]*\$', multiLine: true), '')
        ];
      }

      var buffer = StringBuffer();
      for (var patchUri in library.patches) {
        // Note: VM targets enumerate more than one patch file, they are
        // currently written so that the first file is a valid patch file and
        // all other files can be appended at the end.
        buffer.write(File.fromUri(patchUri).readAsStringSync());
      }
      var patchContents = '$buffer';

      if (patchContents.isNotEmpty) {
        contents = _patchLibrary(contents, patchContents, useNnbd: useNnbd);
      }

      if (contents != null) {
        for (var i = 0; i < outUris.length; i++) {
          _writeSync(outUris[i], contents[i]);
        }
      } else {
        exitCode = 2;
      }
    }
  }

  var outLibrariesDart =
      outLibRoot.resolve('_internal/sdk_library_metadata/lib/libraries.dart');
  _writeSync(outLibrariesDart,
      _generateLibrariesDart(libRoot, specification, useNnbd));

  var experimentsPath = '_internal/allowed_experiments.json';
  _writeSync(
    outLibRoot.resolve(experimentsPath),
    File.fromUri(libRoot.resolve(experimentsPath)).readAsStringSync(),
  );
}

/// Writes a file, creating the directory if needed.
void _writeSync(Uri fileUri, String contents) {
  var outDir = Directory.fromUri(fileUri.resolve('.'));
  if (!outDir.existsSync()) outDir.createSync(recursive: true);

  File.fromUri(fileUri).writeAsStringSync(contents);
}

final _parser = ArgParser()
  ..addFlag('nnbd',
      help: 'Whether to enable the nnbd feature.', defaultsTo: false)
  ..addFlag('merge-parts',
      help: 'Whether to merge part files. '
          'Technically this is not necessary, but dartanalyzer '
          'produces less warnings when enabling this flag.',
      defaultsTo: false)
  ..addOption('libraries',
      help: 'Path to a libraries.json specification file (required). '
          'All libary URIs within libraries.json are expected to be somewhere '
          'under the directory containing the libraries.json file. Reaching '
          'out above such directory is generally not supported. Today it is '
          'only allowed for the nnbd sdk to reuse libraries of the non-nnbd '
          'sdk, in which case the path starts with "../../sdk/lib/".')
  ..addOption('out', help: 'Path to an output folder (required).')
  ..addOption('target',
      help: 'The target tool. '
          'This name matches one of the possible targets in libraries.json '
          'and it is used to pick which patch files will be applied.',
      allowed: ['dartdevc', 'dart2js', 'dart2js_server', 'vm', 'flutter']);

/// Merges dart:* library code with code from *_patch.dart file.
///
/// Takes a list of the library's parts contents, with the main library contents
/// first in the list, and the contents of the patch file.
///
/// The result will have `@patch` implementations merged into the correct place
/// (e.g. the class or top-level function declaration) and all other
/// declarations introduced by the patch will be placed into the main library
/// file.
///
/// This is purely a syntactic transformation. Unlike dart2js patch files, there
/// is no semantic meaning given to the *_patch files, and they do not magically
/// get their own library scope, etc.
///
/// Editorializing: the dart2js approach requires a Dart front end such as
/// package:analyzer to semantically model a feature beyond what is specified
/// in the Dart language. Since this feature is only for the convenience of
/// writing the dart:* libraries, and not a tool given to Dart developers, it
/// seems like a non-ideal situation. Instead we keep the preprocessing simple.
List<String> _patchLibrary(List<String> partsContents, String patchContents,
    {bool useNnbd = false}) {
  var results = <StringEditBuffer>[];

  // Parse the patch first. We'll need to extract bits of this as we go through
  // the other files.
  var patchFinder = PatchFinder.parseAndVisit(patchContents, useNnbd: useNnbd);

  // Merge `external` declarations with the corresponding `@patch` code.
  var failed = false;
  for (var partContent in partsContents) {
    var partEdits = StringEditBuffer(partContent);
    var partUnit = _parseString(partContent, useNnbd: useNnbd).unit;
    var patcher = PatchApplier(partEdits, patchFinder);
    partUnit.accept(patcher);
    if (!failed) failed = patcher.patchWasMissing;
    results.add(partEdits);
  }
  if (failed) return null;
  return List<String>.from(results.map((e) => e.toString()));
}

/// Merge `@patch` declarations into `external` declarations.
class PatchApplier extends GeneralizingAstVisitor<void> {
  final StringEditBuffer edits;
  final PatchFinder patch;

  bool _isLibrary = true; // until proven otherwise.
  bool patchWasMissing = false;

  PatchApplier(this.edits, this.patch);

  @override
  void visitCompilationUnit(CompilationUnit node) {
    super.visitCompilationUnit(node);
    if (_isLibrary) _mergeUnpatched(node);
  }

  void _merge(AstNode node, int pos) {
    var code = patch.contents.substring(node.offset, node.end);
    edits.insert(pos, '\n' + code);
  }

  /// Merges directives and declarations that are not `@patch` into the library.
  void _mergeUnpatched(CompilationUnit unit) {
    // Merge imports from the patch
    // TODO(jmesserly): remove duplicate imports

    // To patch a library, we must have a library directive
    var libDir = unit.directives.first as LibraryDirective;
    var importPos = unit.directives
        .lastWhere((d) => d is ImportDirective, orElse: () => libDir)
        .end;
    for (var d in patch.unit.directives.whereType<ImportDirective>()) {
      _merge(d, importPos);
    }

    var partPos = unit.directives.last.end;
    for (var d in patch.unit.directives.whereType<PartDirective>()) {
      _merge(d, partPos);
    }

    // Merge declarations from the patch
    var declPos = edits.original.length;
    for (var d in patch.mergeDeclarations) {
      _merge(d, declPos);
    }
  }

  @override
  void visitPartOfDirective(PartOfDirective node) {
    _isLibrary = false;
  }

  @override
  void visitFunctionDeclaration(FunctionDeclaration node) {
    _maybePatch(node);
  }

  /// Merge patches and extensions into the class
  @override
  void visitClassDeclaration(ClassDeclaration node) {
    node.members.forEach(_maybePatch);

    var mergeMembers = patch.mergeMembers[_qualifiedName(node)];
    if (mergeMembers == null) return;

    // Merge members from the patch
    var pos = node.members.last.end;
    for (var member in mergeMembers) {
      var code = patch.contents.substring(member.offset, member.end);
      edits.insert(pos, '\n\n  ' + code);
    }
  }

  void _maybePatch(Declaration node) {
    if (node is FieldDeclaration) return;

    var externalKeyword = (node as dynamic).externalKeyword as Token;
    if (externalKeyword == null) return;

    var name = _qualifiedName(node);
    var patchNode = patch.patches[name];
    if (patchNode == null) {
      // *.fromEnvironment are left unpatched by dart2js and are handled via
      // codegen.
      if (name != 'bool.fromEnvironment' &&
          name != 'int.fromEnvironment' &&
          name != 'String.fromEnvironment') {
        print('warning: patch not found for $name: $node');
        // TODO(sigmund): delete this fail logic? Rather than emit an empty
        // file, it's more useful to emit a file with missing patches.
        // patchWasMissing = true;
      }
      return;
    }

    var patchMeta = patchNode.metadata.lastWhere(_isPatchAnnotation);
    var start = patchMeta.endToken.next.offset;
    var code = patch.contents.substring(start, patchNode.end);

    // Const factory constructors can't be legally parsed from the patch file,
    // so we need to omit the "const" there, but still preserve it.
    if (node is ConstructorDeclaration &&
        node.constKeyword != null &&
        patchNode is ConstructorDeclaration &&
        patchNode.constKeyword == null) {
      code = 'const $code';
    }

    // For some node like static fields, the node's offset doesn't include
    // the external keyword. Also starting from the keyword lets us preserve
    // documentation comments.
    edits.replace(externalKeyword.offset, node.end, code);
  }
}

class PatchFinder extends GeneralizingAstVisitor<void> {
  final String contents;
  final CompilationUnit unit;

  final patches = <String, Declaration>{};
  final mergeMembers = <String, List<ClassMember>>{};
  final mergeDeclarations = <CompilationUnitMember>[];

  PatchFinder.parseAndVisit(String contents, {bool useNnbd})
      : contents = contents,
        unit = _parseString(contents, useNnbd: useNnbd).unit {
    visitCompilationUnit(unit);
  }

  @override
  void visitCompilationUnitMember(CompilationUnitMember node) {
    mergeDeclarations.add(node);
  }

  @override
  void visitClassDeclaration(ClassDeclaration node) {
    if (_isPatch(node)) {
      var members = <ClassMember>[];
      for (var member in node.members) {
        if (_isPatch(member)) {
          patches[_qualifiedName(member)] = member;
        } else {
          members.add(member);
        }
      }
      if (members.isNotEmpty) {
        mergeMembers[_qualifiedName(node)] = members;
      }
    } else {
      mergeDeclarations.add(node);
    }
  }

  @override
  void visitFunctionDeclaration(FunctionDeclaration node) {
    if (_isPatch(node)) {
      patches[_qualifiedName(node)] = node;
    } else {
      mergeDeclarations.add(node);
    }
  }

  @override
  void visitFunctionBody(node) {} // skip method bodies
}

String _qualifiedName(Declaration node) {
  var result = '';

  var parent = node.parent;
  if (parent is ClassDeclaration) {
    result = '${parent.name.name}.';
  }

  var name = (node as dynamic).name as SimpleIdentifier;
  if (name != null) result += name.name;

  // Make sure setters and getters don't collide.
  if (node is FunctionDeclaration && node.isSetter ||
      node is MethodDeclaration && node.isSetter) {
    result += '=';
  }

  return result;
}

bool _isPatch(AnnotatedNode node) => node.metadata.any(_isPatchAnnotation);

bool _isPatchAnnotation(Annotation m) =>
    m.name.name == 'patch' && m.constructorName == null && m.arguments == null;

/// Editable string buffer.
///
/// Applies a series of edits (insertions, removals, replacements) using
/// original location information, and composes them into the edited string.
///
/// For example, starting with a parsed AST with original source locations,
/// this type allows edits to be made without regards to other edits.
class StringEditBuffer {
  final String original;
  final _edits = <_StringEdit>[];

  /// Creates a new transaction.
  StringEditBuffer(this.original);

  bool get hasEdits => _edits.isNotEmpty;

  /// Edit the original text, replacing text on the range [begin] and
  /// exclusive [end] with the [replacement] string.
  void replace(int begin, int end, String replacement) {
    _edits.add(_StringEdit(begin, end, replacement));
  }

  /// Insert [string] at [offset].
  /// Equivalent to `replace(offset, offset, string)`.
  void insert(int offset, String string) => replace(offset, offset, string);

  /// Remove text from the range [begin] to exclusive [end].
  /// Equivalent to `replace(begin, end, '')`.
  void remove(int begin, int end) => replace(begin, end, '');

  /// Applies all pending [edit]s and returns a new string.
  ///
  /// This method is non-destructive: it does not discard existing edits or
  /// change the [original] string. Further edits can be added and this method
  /// can be called again.
  ///
  /// Throws [UnsupportedError] if the edits were overlapping. If no edits were
  /// made, the original string will be returned.
  @override
  String toString() {
    var sb = StringBuffer();
    if (_edits.isEmpty) return original;

    // Sort edits by start location.
    _edits.sort();

    var consumed = 0;
    for (var edit in _edits) {
      if (consumed > edit.begin) {
        sb = StringBuffer();
        sb.write('overlapping edits. Insert at offset ');
        sb.write(edit.begin);
        sb.write(' but have consumed ');
        sb.write(consumed);
        sb.write(' input characters. List of edits:');
        for (var e in _edits) {
          sb.write('\n    ');
          sb.write(e);
        }
        throw UnsupportedError(sb.toString());
      }

      // Add characters from the original string between this edit and the last
      // one, if any.
      var betweenEdits = original.substring(consumed, edit.begin);
      sb.write(betweenEdits);
      sb.write(edit.replace);
      consumed = edit.end;
    }

    // Add any text from the end of the original string that was not replaced.
    sb.write(original.substring(consumed));
    return sb.toString();
  }
}

class _StringEdit implements Comparable<_StringEdit> {
  final int begin;
  final int end;
  final String replace;

  _StringEdit(this.begin, this.end, this.replace);

  int get length => end - begin;

  @override
  String toString() => '(Edit @ $begin,$end: "$replace")';

  @override
  int compareTo(_StringEdit other) {
    var diff = begin - other.begin;
    if (diff != 0) return diff;
    return end - other.end;
  }
}

ParseStringResult _parseString(String source, {bool useNnbd}) {
  var features = FeatureSet.fromEnableFlags2(
    sdkLanguageVersion: Version.parse('2.10.0'),
    flags: [if (useNnbd) 'non-nullable'],
  );
  return parseString(content: source, featureSet: features);
}

/// Use the data from a libraries.json specification to generate the contents
/// of `sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart`, which is
/// needed by dartdevc-legacy and dartanalyzer.
String _generateLibrariesDart(
    Uri libBaseUri, TargetLibrariesSpecification specification, bool usdNnbd) {
  var contents = StringBuffer();
  contents.write(_LIBRARIES_DART_PREFIX);
  for (var library in specification.allLibraries) {
    var path = relativizeLibraryUri(libBaseUri, library.uri, usdNnbd);
    contents.write('  "${library.name}": \n'
        '      const LibraryInfo("$path",\n'
        '          categories: "Client,Server"),\n');
  }
  contents.write(_LIBRARIES_DART_SUFFIX);
  return '$contents';
}

String relativizeLibraryUri(Uri libRoot, Uri uri, bool useNnbd) {
  var relativePath = relativizeUri(libRoot, uri, isWindows);
  // During the nnbd-migration we may have paths that reach out into the
  // non-nnbd directory.
  if (relativePath.startsWith('..')) {
    if (!useNnbd || !relativePath.startsWith('../../sdk/lib/')) {
      print("error: can't handle libraries that live out of the sdk folder"
          ': $relativePath');
      exit(1);
    }
    relativePath = relativePath.replaceFirst('../../sdk/lib/', '');
  }
  return relativePath;
}

final _LIBRARIES_DART_PREFIX = r'''
library libraries;

const int DART2JS_PLATFORM = 1;
const int VM_PLATFORM = 2;

enum Category { client, server, embedded }

Category parseCategory(String name) {
  switch (name) {
    case "Client":
      return Category.client;
    case "Server":
      return Category.server;
    case "Embedded":
      return Category.embedded;
  }
  return null;
}

const Map<String, LibraryInfo> libraries = const {
''';

final _LIBRARIES_DART_SUFFIX = r'''
};

class LibraryInfo {
  final String path;
  final String _categories;
  final String dart2jsPath;
  final String dart2jsPatchPath;
  final bool documented;
  final int platforms;
  final bool implementation;
  final Maturity maturity;

  const LibraryInfo(this.path,
      {String categories: "",
      this.dart2jsPath,
      this.dart2jsPatchPath,
      this.implementation: false,
      this.documented: true,
      this.maturity: Maturity.UNSPECIFIED,
      this.platforms: DART2JS_PLATFORM | VM_PLATFORM})
      : _categories = categories;

  bool get isDart2jsLibrary => (platforms & DART2JS_PLATFORM) != 0;
  bool get isVmLibrary => (platforms & VM_PLATFORM) != 0;
  List<Category> get categories {
    // `"".split(,)` returns [""] not [], so we handle that case separately.
    if (_categories == "") return const <Category>[];
    return _categories.split(",").map(parseCategory).toList();
  }

  bool get isInternal => categories.isEmpty;
  String get categoriesString => _categories;
}

class Maturity {
  final int level;
  final String name;
  final String description;

  const Maturity(this.level, this.name, this.description);

  String toString() => "$name: $level\n$description\n";

  static const Maturity DEPRECATED = const Maturity(0, "Deprecated",
      "This library will be remove before next major release.");

  static const Maturity EXPERIMENTAL = const Maturity(
      1,
      "Experimental",
      "This library is experimental and will likely change or be removed\n"
          "in future versions.");

  static const Maturity UNSTABLE = const Maturity(
      2,
      "Unstable",
      "This library is in still changing and have not yet endured\n"
          "sufficient real-world testing.\n"
          "Backwards-compatibility is NOT guaranteed.");

  static const Maturity WEB_STABLE = const Maturity(
      3,
      "Web Stable",
      "This library is tracking the DOM evolution as defined by WC3.\n"
          "Backwards-compatibility is NOT guaranteed.");

  static const Maturity STABLE = const Maturity(
      4,
      "Stable",
      "The library is stable. API backwards-compatibility is guaranteed.\n"
          "However implementation details might change.");

  static const Maturity LOCKED = const Maturity(5, "Locked",
      "This library will not change except when serious bugs are encountered.");

  static const Maturity UNSPECIFIED = const Maturity(-1, "Unspecified",
      "The maturity for this library has not been specified.");
}
''';
