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

import 'dart:collection';
import 'package:meta/meta.dart';

import '../compiler/js_names.dart' as js_ast;
import '../js_ast/js_ast.dart' as js_ast;
import '../js_ast/js_ast.dart' show js;

/// Shared code between Analyzer and Kernel backends.
///
/// This class should only implement functionality that depends purely on JS
/// classes, rather than on Analyzer/Kernel types.
abstract class SharedCompiler<Library, Class, InterfaceType, FunctionNode> {
  /// When inside a `[]=` operator, this will be a non-null value that should be
  /// returned by any `return;` statement.
  ///
  /// This lets DDC use the setter method's return value directly.
  final List<js_ast.Identifier> _operatorSetResultStack = [];

  /// Private member names in this module, organized by their library.
  final _privateNames = HashMap<Library, HashMap<String, js_ast.TemporaryId>>();

  /// Extension member symbols for adding Dart members to JS types.
  ///
  /// These are added to the [extensionSymbolsModule]; see that field for more
  /// information.
  final _extensionSymbols = <String, js_ast.TemporaryId>{};

  /// The set of libraries we are currently compiling, and the temporaries used
  /// to refer to them.
  final _libraries = <Library, js_ast.Identifier>{};

  /// Imported libraries, and the temporaries used to refer to them.
  final _imports = <Library, js_ast.TemporaryId>{};

  /// The identifier used to reference DDC's core "dart:_runtime" library from
  /// generated JS code, typically called "dart" e.g. `dart.dcall`.
  @protected
  js_ast.Identifier runtimeModule;

  /// The identifier used to reference DDC's "extension method" symbols, used to
  /// safely add Dart-specific member names to JavaScript classes, such as
  /// primitive types (e.g. String) or DOM types in "dart:html".
  @protected
  js_ast.Identifier extensionSymbolsModule;

  /// Whether we're currently building the SDK, which may require special
  /// bootstrapping logic.
  ///
  /// This is initialized by [startModule], which must be called before
  /// accessing this field.
  @protected
  bool isBuildingSdk;

  /// The temporary variable that stores named arguments (these are passed via a
  /// JS object literal, to match JS conventions).
  @protected
  final namedArgumentTemp = js_ast.TemporaryId('opts');

  /// The list of output module items, in the order they need to be emitted in.
  @protected
  final moduleItems = <js_ast.ModuleItem>[];

  /// Like [moduleItems] but for items that should be emitted after classes.
  ///
  /// This is used for deferred supertypes of mutually recursive non-generic
  /// classes.
  @protected
  final afterClassDefItems = <js_ast.ModuleItem>[];

  /// The type used for private Dart [Symbol]s.
  @protected
  InterfaceType get privateSymbolType;

  /// The type used for public Dart [Symbol]s.
  @protected
  InterfaceType get internalSymbolType;

  /// The current library being compiled.
  @protected
  Library get currentLibrary;

  /// The library for dart:core in the SDK.
  @protected
  Library get coreLibrary;

  /// The import URI of current library.
  @protected
  Uri get currentLibraryUri;

  /// The current function being compiled, if any.
  @protected
  FunctionNode get currentFunction;

  /// Choose a canonical name from the [library] element.
  @protected
  String jsLibraryName(Library library);

  /// Choose a module-unique name from the [library] element.
  ///
  /// Returns null if no alias exists or there are multiple output paths
  /// (e.g., when compiling the Dart SDK).
  ///
  /// This never uses the library's name (the identifier in the `library`
  /// declaration) as it doesn't have any meaningful rules enforced.
  @protected
  String jsLibraryAlias(Library library);

  /// Debugger friendly name for a Dart [library].
  @protected
  String jsLibraryDebuggerName(Library library);

  /// Debugger friendly names for all parts in a Dart [library].
  @protected
  Iterable<String> jsPartDebuggerNames(Library library);

  /// Gets the module import URI that contains [library].
  @protected
  String libraryToModule(Library library);

  /// Returns true if the library [l] is "dart:_runtime".
  @protected
  bool isSdkInternalRuntime(Library l);

  /// Whether any superclass of [c] defines a static [name].
  @protected
  bool superclassHasStatic(Class c, String name);

  /// Emits the expression necessary to access a constructor of [type];
  @protected
  js_ast.Expression emitConstructorAccess(InterfaceType type);

  /// When compiling the body of a `operator []=` method, this will be non-null
  /// and will indicate the the value that should be returned from any `return;`
  /// statements.
  js_ast.Identifier get _operatorSetResult {
    var stack = _operatorSetResultStack;
    return stack.isEmpty ? null : stack.last;
  }

  /// Called when starting to emit methods/functions, in particular so we can
  /// implement special handling of the user-defined `[]=` and `==` methods.
  ///
  /// See also [exitFunction] and [emitReturnStatement].
  @protected
  void enterFunction(String name, List<js_ast.Parameter> formals,
      bool Function() isLastParamMutated) {
    if (name == '[]=') {
      _operatorSetResultStack.add(isLastParamMutated()
          ? js_ast.TemporaryId((formals.last as js_ast.Identifier).name)
          : formals.last as js_ast.Identifier);
    } else {
      _operatorSetResultStack.add(null);
    }
  }

  /// Called when finished emitting methods/functions, and must correspond to a
  /// previous [enterFunction] call.
  @protected
  js_ast.Block exitFunction(
      String name, List<js_ast.Parameter> formals, js_ast.Block code) {
    if (name == "==" &&
        formals.isNotEmpty &&
        currentLibraryUri.scheme != 'dart') {
      // In Dart `operator ==` methods are not called with a null argument.
      // This is handled before calling them. For performance reasons, we push
      // this check inside the method, to simplify our `equals` helper.
      //
      // TODO(jmesserly): in most cases this check is not necessary, because
      // the Dart code already handles it (typically by an `is` check).
      // Eliminate it when possible.
      code = js
          .block('{ if (# == null) return false; #; }', [formals.first, code]);
    }
    var setOperatorResult = _operatorSetResultStack.removeLast();
    if (setOperatorResult != null) {
      // []= methods need to return the value. We could also address this at
      // call sites, but it's less code size to handle inside the operator.
      var valueParam = formals.last;
      var statements = code.statements;
      if (statements.isEmpty || !statements.last.alwaysReturns) {
        statements.add(js_ast.Return(setOperatorResult));
      }
      if (!identical(setOperatorResult, valueParam)) {
        // If the value parameter was mutated, then we use a temporary
        // variable to track the initial value
        formals.last = setOperatorResult;
        code = js
            .block('{ let # = #; #; }', [valueParam, setOperatorResult, code]);
      }
    }
    return code;
  }

  /// Emits a return statement `return <value>;`, handling special rules for
  /// the `operator []=` method.
  @protected
  js_ast.Statement emitReturnStatement(js_ast.Expression value) {
    if (_operatorSetResult != null) {
      var result = js_ast.Return(_operatorSetResult);
      return value != null
          ? js_ast.Block([value.toStatement(), result])
          : result;
    }
    return value != null ? value.toReturn() : js_ast.Return();
  }

  /// Prepends the `dart.` and then uses [js.call] to parse the specified JS
  /// [code] template, passing [args].
  ///
  /// For example:
  ///
  ///     runtimeCall('asInt(#)', [<expr>])
  ///
  /// Generates a JS AST representing:
  ///
  ///     dart.asInt(<expr>)
  ///
  @protected
  js_ast.Expression runtimeCall(String code, [List<Object> args]) =>
      js.call('#.$code', <Object>[runtimeModule, ...?args]);

  /// Calls [runtimeCall] and uses `toStatement()` to convert the resulting
  /// expression into a statement.
  @protected
  js_ast.Statement runtimeStatement(String code, [List<Object> args]) =>
      runtimeCall(code, args).toStatement();

  /// Emits a private name JS Symbol for [name] scoped to the Dart [library].
  ///
  /// If the same name is used in multiple libraries in the same module,
  /// distinct symbols will be used, so each library will have distinct private
  /// member names, that won't collide at runtime, as required by the Dart
  /// language spec.
  @protected
  js_ast.TemporaryId emitPrivateNameSymbol(Library library, String name) {
    /// Initializes the JS `Symbol` for the private member [name] in [library].
    ///
    /// If the library is in the current JS module ([_libraries] contains it),
    /// the private name will be created and exported. The exported symbol is
    /// used for a few things:
    ///
    /// - private fields of constant objects
    /// - stateful hot reload (not yet implemented)
    /// - correct library scope in REPL (not yet implemented)
    ///
    /// If the library is imported, then the existing private name will be
    /// retrieved from it. In both cases, we use the same `dart.privateName`
    /// runtime call.
    js_ast.TemporaryId initPrivateNameSymbol() {
      var idName = name.endsWith('=') ? name.replaceAll('=', '_') : name;
      idName = idName.replaceAll('.', '_');
      var id = js_ast.TemporaryId(idName);
      moduleItems.add(js.statement('const # = #.privateName(#, #)',
          [id, runtimeModule, emitLibraryName(library), js.string(name)]));
      return id;
    }

    var privateNames = _privateNames.putIfAbsent(library, () => HashMap());
    return privateNames.putIfAbsent(name, initPrivateNameSymbol);
  }

  /// Emits a private name JS Symbol for [memberName] unique to a Dart
  /// class [className].
  ///
  /// This is now required for fields of constant objects that may be
  /// overridden within the same library.
  @protected
  js_ast.TemporaryId emitClassPrivateNameSymbol(
      Library library, String className, String memberName) {
    return emitPrivateNameSymbol(library, '$className.$memberName');
  }

  /// Emits an expression to set the property [nameExpr] on the class [className],
  /// with [value].
  ///
  /// This will use `className.name = value` if possible, otherwise it will use
  /// `dart.defineValue(className, name, value)`. This is required when
  /// `FunctionNode.prototype` already defins a getters with the same name.
  @protected
  js_ast.Expression defineValueOnClass(Class c, js_ast.Expression className,
      js_ast.Expression nameExpr, js_ast.Expression value) {
    var args = [className, nameExpr, value];
    if (nameExpr is js_ast.LiteralString) {
      var name = nameExpr.valueWithoutQuotes;
      if (js_ast.isFunctionPrototypeGetter(name) ||
          superclassHasStatic(c, name)) {
        return runtimeCall('defineValue(#, #, #)', args);
      }
    }
    return js.call('#.# = #', args);
  }

  /// Caches a constant (list/set/map or class instance) in a variable, so it's
  /// only canonicalized once at this location in the code, which improves
  /// performance.
  ///
  /// This method ensures the constant is not initialized until use.
  ///
  /// The expression [jsExpr] should contain the already-canonicalized constant.
  /// If the constant is not canonicalized yet, it should be wrapped in the
  /// appropriate call, such as:
  ///
  /// - dart.constList (for Lists),
  /// - dart.constMap (for Maps),
  /// - dart.constSet (for Sets),
  /// - dart.const (for other instances of classes)
  ///
  /// [canonicalizeConstObject] can be used for class instances; it will wrap
  /// the expression in `dart.const` and then call this method.
  ///
  /// If the same consant is used elsewhere (in this module, or another module),
  /// that will require a second canonicalization. In general it is uncommon
  /// to define the same large constant (such as lists, maps) in different
  /// locations, because that requires copy+paste, so in practice this
  /// optimization is rather effective (we should consider caching once
  /// per-module, though, as that would be relatively easy for the compiler to
  /// implement once we have a single Kernel backend).
  @protected
  js_ast.Expression cacheConst(js_ast.Expression jsExpr) {
    if (currentFunction == null) return jsExpr;

    var temp = js_ast.TemporaryId('const');
    moduleItems.add(js.statement('let #;', [temp]));
    return js.call('# || (# = #)', [temp, temp, jsExpr]);
  }

  /// Emits a Dart Symbol with the given member [symbolName].
  ///
  /// If the symbol refers to a private name, its library will be set to the
  /// [currentLibrary], so the Symbol is scoped properly.
  @protected
  js_ast.Expression emitDartSymbol(String symbolName) {
    // TODO(vsm): Handle qualified symbols correctly.
    var last = symbolName.split('.').last;
    var name = js.escapedString(symbolName, "'");
    js_ast.Expression result;
    if (last.startsWith('_')) {
      var nativeSymbol = emitPrivateNameSymbol(currentLibrary, last);
      result = js.call('new #.new(#, #)',
          [emitConstructorAccess(privateSymbolType), name, nativeSymbol]);
    } else {
      result = js.call(
          'new #.new(#)', [emitConstructorAccess(internalSymbolType), name]);
    }
    return canonicalizeConstObject(result);
  }

  /// Calls the `dart.const` function in "dart:_runtime" to canonicalize a
  /// constant instance of a user-defined class stored in [expr].
  @protected
  js_ast.Expression canonicalizeConstObject(js_ast.Expression expr) =>
      cacheConst(runtimeCall('const(#)', [expr]));

  /// Emits preamble for the module containing [libraries], and returns the
  /// list of module items for further items to be added.
  ///
  /// The preamble consists of initializing the identifiers for each library,
  /// that will be used to store their members. It also generates the
  /// appropriate ES6 `export` declaration to export them from this module.
  ///
  /// After the code for all of the library members is emitted,
  /// [emitImportsAndExtensionSymbols] should be used to emit imports/extension
  /// symbols into the list returned by this method. Finally, [finishModule]
  /// can be called to complete the module and return the resulting JS AST.
  ///
  /// This also initializes several fields: [isBuildingSdk], [runtimeModule],
  /// [extensionSymbolsModule], as well as the [_libraries] map needed by
  /// [emitLibraryName].
  @protected
  List<js_ast.ModuleItem> startModule(Iterable<Library> libraries) {
    isBuildingSdk = libraries.any(isSdkInternalRuntime);
    if (isBuildingSdk) {
      // Don't allow these to be renamed when we're building the SDK.
      // There is JS code in dart:* that depends on their names.
      runtimeModule = js_ast.Identifier('dart');
      extensionSymbolsModule = js_ast.Identifier('dartx');
    } else {
      // Otherwise allow these to be renamed so users can write them.
      runtimeModule = js_ast.TemporaryId('dart');
      extensionSymbolsModule = js_ast.TemporaryId('dartx');
    }

    // Initialize our library variables.
    var items = <js_ast.ModuleItem>[];
    var exports = <js_ast.NameSpecifier>[];

    if (isBuildingSdk) {
      // Bootstrap the ability to create Dart library objects.
      var libraryProto = js_ast.TemporaryId('_library');
      items.add(js.statement('const # = Object.create(null)', libraryProto));
      items.add(js.statement(
          'const # = Object.create(#)', [runtimeModule, libraryProto]));
      items.add(js.statement('#.library = #', [runtimeModule, libraryProto]));
      exports.add(js_ast.NameSpecifier(runtimeModule));
    }

    for (var library in libraries) {
      if (isBuildingSdk && isSdkInternalRuntime(library)) {
        _libraries[library] = runtimeModule;
        continue;
      }
      var libraryId = js_ast.TemporaryId(jsLibraryName(library));
      _libraries[library] = libraryId;
      var alias = jsLibraryAlias(library);
      var aliasId = alias == null ? null : js_ast.TemporaryId(alias);

      items.add(js.statement(
          'const # = Object.create(#.library)', [libraryId, runtimeModule]));
      exports.add(js_ast.NameSpecifier(libraryId, asName: aliasId));
    }

    // dart:_runtime has a magic module that holds extension method symbols.
    // TODO(jmesserly): find a cleaner design for this.
    if (isBuildingSdk) {
      var id = extensionSymbolsModule;
      items.add(js.statement(
          'const # = Object.create(#.library)', [id, runtimeModule]));
      exports.add(js_ast.NameSpecifier(id));
    }

    items.add(js_ast.ExportDeclaration(js_ast.ExportClause(exports)));

    if (isBuildingSdk) {
      // Initialize the private name function.
      // To bootstrap the SDK, this needs to be emitted before other code.
      var symbol = js_ast.TemporaryId('_privateNames');
      items.add(js.statement('const # = Symbol("_privateNames")', symbol));
      items.add(js.statement(r'''
        #.privateName = function(library, name) {
          let names = library[#];
          if (names == null) names = library[#] = new Map();
          let symbol = names.get(name);
          if (symbol == null) names.set(name, symbol = Symbol(name));
          return symbol;
        }
      ''', [runtimeModule, symbol, symbol]));
    }

    return items;
  }

  /// Returns the canonical name to refer to the Dart library.
  @protected
  js_ast.Identifier emitLibraryName(Library library) {
    // It's either one of the libraries in this module, or it's an import.
    var libraryId = js_ast.TemporaryId(jsLibraryName(library));
    return _libraries[library] ??
        _imports.putIfAbsent(library, () => libraryId);
  }

  /// Emits imports and extension methods into [items].
  @protected
  void emitImportsAndExtensionSymbols(List<js_ast.ModuleItem> items) {
    var modules = Map<String, List<Library>>();

    for (var import in _imports.keys) {
      modules.putIfAbsent(libraryToModule(import), () => []).add(import);
    }

    String coreModuleName;
    if (!_libraries.containsKey(coreLibrary)) {
      coreModuleName = libraryToModule(coreLibrary);
    }
    modules.forEach((module, libraries) {
      // Generate import directives.
      //
      // Our import variables are temps and can get renamed. Since our renaming
      // is integrated into js_ast, it is aware of this possibility and will
      // generate an "as" if needed. For example:
      //
      //     import {foo} from 'foo';         // if no rename needed
      //     import {foo as foo$} from 'foo'; // if rename was needed
      //
      var imports = libraries.map((library) {
        var alias = jsLibraryAlias(library);
        if (alias != null) {
          var aliasId = js_ast.TemporaryId(alias);
          return js_ast.NameSpecifier(aliasId, asName: _imports[library]);
        }
        return js_ast.NameSpecifier(_imports[library]);
      }).toList();
      if (module == coreModuleName) {
        imports.add(js_ast.NameSpecifier(runtimeModule));
        imports.add(js_ast.NameSpecifier(extensionSymbolsModule));
      }

      items.add(js_ast.ImportDeclaration(
          namedImports: imports, from: js.string(module, "'")));
    });

    // Initialize extension symbols
    _extensionSymbols.forEach((name, id) {
      js_ast.Expression value =
          js_ast.PropertyAccess(extensionSymbolsModule, propertyName(name));
      if (isBuildingSdk) {
        value = js.call('# = Symbol(#)', [value, js.string("dartx.$name")]);
      }
      items.add(js.statement('const # = #;', [id, value]));
    });
  }

  void _emitDebuggerExtensionInfo(String name) {
    var properties = <js_ast.Property>[];
    var parts = <js_ast.Property>[];
    _libraries.forEach((library, value) {
      // TODO(jacobr): we could specify a short library name instead of the
      // full library uri if we wanted to save space.
      var libraryName = js.escapedString(jsLibraryDebuggerName(library));
      properties.add(js_ast.Property(libraryName, value));
      var partNames = jsPartDebuggerNames(library);
      if (partNames.isNotEmpty) {
        parts.add(js_ast.Property(libraryName, js.stringArray(partNames)));
      }
    });
    var module = js_ast.ObjectInitializer(properties, multiline: true);
    var partMap = js_ast.ObjectInitializer(parts, multiline: true);

    // Track the module name for each library in the module.
    // This data is only required for debugging.
    moduleItems.add(js.statement(
        '#.trackLibraries(#, #, #, $sourceMapLocationID);',
        [runtimeModule, js.string(name), module, partMap]));
  }

  /// Finishes the module created by [startModule], by combining the preable
  /// [items] with the [moduleItems] that have been emitted.
  ///
  /// The [moduleName] should specify the module's name, and the items should
  /// be the list resulting from startModule, with additional items added,
  /// but not including the contents of moduleItems (which will be handled by
  /// this method itself).
  ///
  /// Note, this function mutates the items list and returns it as the `body`
  /// field of the result.
  @protected
  js_ast.Program finishModule(
      List<js_ast.ModuleItem> items, String moduleName) {
    // TODO(jmesserly): there's probably further consolidation we can do
    // between DDC's two backends, by moving more code into this method, as the
    // code between `startModule` and `finishModule` is very similar in both.
    _emitDebuggerExtensionInfo(moduleName);

    // Add the module's code (produced by visiting compilation units, above)
    _copyAndFlattenBlocks(items, moduleItems);
    moduleItems.clear();

    // Build the module.
    return js_ast.Program(items, name: moduleName);
  }

  /// Flattens blocks in [items] to a single list.
  ///
  /// This will not flatten blocks that are marked as being scopes.
  void _copyAndFlattenBlocks(
      List<js_ast.ModuleItem> result, Iterable<js_ast.ModuleItem> items) {
    for (var item in items) {
      if (item is js_ast.Block && !item.isScope) {
        _copyAndFlattenBlocks(result, item.statements);
      } else if (item != null) {
        result.add(item);
      }
    }
  }

  /// This is an internal method used by [_emitMemberName] and the
  /// optimized `dart:_runtime extensionSymbol` builtin to get the symbol
  /// for `dartx.<name>`.
  ///
  /// Do not call this directly; you want [_emitMemberName], which knows how to
  /// handle the many details involved in naming.
  @protected
  js_ast.TemporaryId getExtensionSymbolInternal(String name) {
    return _extensionSymbols.putIfAbsent(
        name,
        () => js_ast.TemporaryId(
            '\$${js_ast.friendlyNameForDartOperator[name] ?? name}'));
  }

  /// Shorthand for identifier-like property names.
  /// For now, we emit them as strings and the printer restores them to
  /// identifiers if it can.
  // TODO(jmesserly): avoid the round tripping through quoted form.
  @protected
  js_ast.LiteralString propertyName(String name) => js.string(name, "'");

  /// Unique identifier indicating the location to inline the source map.
  ///
  /// We cannot generate the source map before the script it is for is
  /// generated so we have generate the script including this identifier in the
  /// JS AST, and then replace it once the source map is generated.
  static const String sourceMapLocationID =
      'SourceMap3G5a8h6JVhHfdGuDxZr1EF9GQC8y0e6u';
}

/// Whether a variable with [name] is referenced in the [node].
bool variableIsReferenced(String name, js_ast.Node node) {
  var finder = _IdentifierFinder.instance;
  finder.nameToFind = name;
  finder.found = false;
  node.accept(finder);
  return finder.found;
}

class _IdentifierFinder extends js_ast.BaseVisitor<void> {
  String nameToFind;
  bool found = false;

  static final instance = _IdentifierFinder();

  @override
  visitIdentifier(node) {
    if (node.name == nameToFind) found = true;
  }

  @override
  visitNode(node) {
    if (!found) super.visitNode(node);
  }
}

class YieldFinder extends js_ast.BaseVisitor {
  bool hasYield = false;
  bool hasThis = false;
  bool _nestedFunction = false;

  @override
  visitThis(js_ast.This node) {
    hasThis = true;
  }

  @override
  visitFunctionExpression(js_ast.FunctionExpression node) {
    var savedNested = _nestedFunction;
    _nestedFunction = true;
    super.visitFunctionExpression(node);
    _nestedFunction = savedNested;
  }

  @override
  visitYield(js_ast.Yield node) {
    if (!_nestedFunction) hasYield = true;
    super.visitYield(node);
  }

  @override
  visitNode(js_ast.Node node) {
    if (hasYield && hasThis) return; // found both, nothing more to do.
    super.visitNode(node);
  }
}

/// Given the function [fn], returns a function declaration statement, binding
/// `this` and `super` if necessary (using an arrow function).
js_ast.Statement toBoundFunctionStatement(
    js_ast.Fun fn, js_ast.Identifier name) {
  if (usesThisOrSuper(fn)) {
    return js.statement('const # = (#) => {#}', [name, fn.params, fn.body]);
  } else {
    return js_ast.FunctionDeclaration(name, fn);
  }
}

/// Returns whether [node] uses `this` or `super`.
bool usesThisOrSuper(js_ast.Expression node) {
  var finder = _ThisOrSuperFinder.instance;
  finder.found = false;
  node.accept(finder);
  return finder.found;
}

class _ThisOrSuperFinder extends js_ast.BaseVisitor<void> {
  bool found = false;

  static final instance = _ThisOrSuperFinder();

  @override
  visitThis(js_ast.This node) {
    found = true;
  }

  @override
  visitSuper(js_ast.Super node) {
    found = true;
  }

  @override
  visitNode(js_ast.Node node) {
    if (!found) super.visitNode(node);
  }
}
