// Copyright (c) 2017, 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:async';
import 'dart:convert' show JsonEncoder;
import 'dart:io';

import 'package:analyzer/analyzer.dart';
import 'package:barback/barback.dart';
import 'package:bazel_worker/bazel_worker.dart';
import 'package:cli_util/cli_util.dart' as cli_util;
import 'package:path/path.dart' as p;

import '../dart.dart';
import '../io.dart';
import 'errors.dart';
import 'module_reader.dart';
import 'scratch_space.dart';
import 'summaries.dart';
import 'workers.dart';

/// JavaScript snippet to determine the directory a script was run from.
final _currentDirectoryScript = r'''
var _currentDirectory = (function () {
  var _url;
  var lines = new Error().stack.split('\n');
  function lookupUrl() {
    if (lines.length > 2) {
      var match = lines[1].match(/^\s+at (.+):\d+:\d+$/);
      // Chrome.
      if (match) return match[1];
      // Chrome nested eval case.
      match = lines[1].match(/^\s+at eval [(](.+):\d+:\d+[)]$/);
      if (match) return match[1];
      // Edge.
      match = lines[1].match(/^\s+at.+\((.+):\d+:\d+\)$/);
      if (match) return match[1];
      // Firefox.
      match = lines[0].match(/[<][@](.+):\d+:\d+$/)
      if (match) return match[1];
    }
    // Safari.
    return lines[0].match(/(.+):\d+:\d+$/)[1];
  }
  _url = lookupUrl();
  var lastSlash = _url.lastIndexOf('/');
  if (lastSlash == -1) return _url;
  var currentDirectory = _url.substring(0, lastSlash + 1);
  return currentDirectory;
})();
''';

/// Returns whether or not [dartId] is an app entrypoint (basically, whether or
/// not it has a `main` function).
Future<bool> isAppEntryPoint(
    AssetId dartId, Future<Asset> getAsset(AssetId id)) async {
  assert(dartId.extension == '.dart');
  var dartAsset = await getAsset(dartId);
  // Skip reporting errors here, dartdevc will report them later with nicer
  // formatting.
  var parsed = parseCompilationUnit(await dartAsset.readAsString(),
      suppressErrors: true);
  return isEntrypoint(parsed);
}

/// Bootstraps the JS module for the entrypoint dart file [dartEntrypointId]
/// with two additional JS files:
///
/// * A `$dartEntrypointId.js` file which is the main entrypoint for the app. It
///   injects a script tag whose src is `require.js` and whose `data-main`
///   attribute points at a `$dartEntrypointId.bootstrap.js` file.
/// * A `$dartEntrypointId.bootstrap.js` file which invokes the top level `main`
///   function from the entrypoint module, after performing some necessary SDK
///   setup.
///
/// In debug mode an empty sourcemap will be output for the entrypoint JS file
/// to satisfy the test package runner (there is no original dart file to map it
/// back to though).
///
/// Synchronously returns a `Map<AssetId, Future<Asset>>` so that you can know
/// immediately what assets will be output.
Map<AssetId, Future<Asset>> bootstrapDartDevcEntrypoint(
    AssetId dartEntrypointId, BarbackMode mode, ModuleReader moduleReader) {
  var bootstrapId = dartEntrypointId.addExtension('.bootstrap.js');
  var jsEntrypointId = dartEntrypointId.addExtension('.js');
  var jsMapEntrypointId = jsEntrypointId.addExtension('.map');

  var outputCompleters = <AssetId, Completer<Asset>>{
    bootstrapId: new Completer(),
    jsEntrypointId: new Completer(),
  };
  var isDebug = mode == BarbackMode.DEBUG;

  if (isDebug) {
    outputCompleters[jsMapEntrypointId] = new Completer<Asset>();
  }

  return _ensureComplete(outputCompleters, () async {
    var module = await moduleReader.moduleFor(dartEntrypointId);

    // The path to the entrypoint JS module as it should appear in the call to
    // `require` in the bootstrap file.
    var moduleDir = topLevelDir(dartEntrypointId.path);
    var appModulePath = p.url.relative(p.url.join(moduleDir, module.id.name),
        from: p.url.dirname(dartEntrypointId.path));

    // The name of the entrypoint dart library within the entrypoint JS module.
    //
    // This is used to invoke `main()` from within the bootstrap script.
    //
    // TODO(jakemac53): Sane module name creation, this only works in the most
    // basic of cases.
    //
    // See https://github.com/dart-lang/sdk/issues/27262 for the root issue
    // which will allow us to not rely on the naming schemes that dartdevc uses
    // internally, but instead specify our own.
    var appModuleScope = p.url
        .split(p.url.withoutExtension(
            p.url.relative(dartEntrypointId.path, from: moduleDir)))
        .join("__")
        .replaceAll('.', '\$46');

    // Map from module name to module path.
    // Modules outside of the `packages` directory have different module path
    // and module names.
    var modulePaths = {appModulePath: appModulePath, 'dart_sdk': 'dart_sdk'};
    var transitiveDeps = await moduleReader.readTransitiveDeps(module);
    for (var dep in transitiveDeps) {
      if (dep.dir != 'lib') {
        var relativePath = p.url.relative(p.url.join(moduleDir, dep.name),
            from: p.url.dirname(bootstrapId.path));
        var jsModuleName = '${dep.dir}/${dep.name}';

        modulePaths[jsModuleName] = relativePath;
      } else {
        var jsModuleName = 'packages/${dep.package}/${dep.name}';
        var actualModulePath = p.url.relative(
            p.url.join(moduleDir, jsModuleName),
            from: p.url.dirname(bootstrapId.path));
        modulePaths[jsModuleName] = actualModulePath;
      }
    }
    var bootstrapContent = new StringBuffer('(function() {\n');
    if (isDebug) {
      bootstrapContent.write('''
$_currentDirectoryScript
let modulePaths = ${const JsonEncoder.withIndent(" ").convert(modulePaths)};

if(!window.\$dartLoader) {
   window.\$dartLoader = {
     moduleIdToUrl: new Map(),
     urlToModuleId: new Map(),
     rootDirectories: new Set(),
   };
}

let customModulePaths = {};
window.\$dartLoader.rootDirectories.add(_currentDirectory);
for (let moduleName of Object.getOwnPropertyNames(modulePaths)) {
  let modulePath = modulePaths[moduleName];
  if (modulePath != moduleName) {
    customModulePaths[moduleName] = modulePath;
  }
  var src = _currentDirectory + modulePath + '.js';
  if (window.\$dartLoader.moduleIdToUrl.has(moduleName)) {
    continue;
  }
  \$dartLoader.moduleIdToUrl.set(moduleName, src);
  \$dartLoader.urlToModuleId.set(src, moduleName);
}
''');
    } else {
      var customModulePaths = <String, String>{};
      modulePaths.forEach((name, path) {
        if (name != path) customModulePaths[name] = path;
      });
      var json = const JsonEncoder.withIndent(" ").convert(customModulePaths);
      bootstrapContent.write('let customModulePaths = ${json};\n');
    }

    bootstrapContent.write('''
// Whenever we fail to load a JS module, try to request the corresponding
// `.errors` file, and log it to the console.
(function() {
  var oldOnError = requirejs.onError;
  requirejs.onError = function(e) {
    if (e.originalError && e.originalError.srcElement) {
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
          console.error(this.responseText);
        }
      };
      xhr.open("GET", e.originalError.srcElement.src + ".errors", true);
      xhr.send();
    }
    // Also handle errors the normal way.
    if (oldOnError) oldOnError(e);
  };
}());

require.config({
    waitSeconds: 30,
    paths: customModulePaths
});

require(["$appModulePath", "dart_sdk"], function(app, dart_sdk) {
  dart_sdk._isolate_helper.startRootIsolate(() => {}, []);
''');

    if (isDebug) {
      bootstrapContent.write('''
  dart_sdk._debugger.registerDevtoolsFormatter();

  if (window.\$dartStackTraceUtility && !window.\$dartStackTraceUtility.ready) {
    window.\$dartStackTraceUtility.ready = true;
    let dart = dart_sdk.dart;
    window.\$dartStackTraceUtility.setSourceMapProvider(
      function(url) {
        var module = window.\$dartLoader.urlToModuleId.get(url);
        if (!module) return null;
        return dart.getSourceMap(module);
      });
  }
  window.postMessage({ type: "DDC_STATE_CHANGE", state: "start" }, "*");
''');
    }

    bootstrapContent.write('''
  app.$appModuleScope.main();
});
})();
''');
    outputCompleters[bootstrapId].complete(
        new Asset.fromString(bootstrapId, bootstrapContent.toString()));

    var bootstrapModuleName = p.withoutExtension(
        p.relative(bootstrapId.path, from: p.dirname(dartEntrypointId.path)));
    var entrypointJsContent = new StringBuffer('''
var el;
''');
    if (isDebug) {
      entrypointJsContent.write('''
el = document.createElement("script");
el.defer = true;
el.async = false;
el.src = "dart_stack_trace_mapper.js";
document.head.appendChild(el);
''');
    }

    entrypointJsContent.write('''
el = document.createElement("script");
el.defer = true;
el.async = false;
el.src = "require.js";
el.setAttribute("data-main", "$bootstrapModuleName");
document.head.appendChild(el);
''');
    outputCompleters[jsEntrypointId].complete(
        new Asset.fromString(jsEntrypointId, entrypointJsContent.toString()));

    if (isDebug) {
      outputCompleters[jsMapEntrypointId].complete(new Asset.fromString(
          jsMapEntrypointId,
          '{"version":3,"sourceRoot":"","sources":[],"names":[],"mappings":"",'
          '"file":""}'));
    }
  });
}

/// Compiles [module] using the `dartdevc` binary from the SDK to a relative
/// path under the package that looks like `$outputDir/${module.id.name}.js`.
///
/// Synchronously returns a `Map<AssetId, Future<Asset>>` so that you can know
/// immediately what assets will be output.
Map<AssetId, Future<Asset>> createDartdevcModule(
    AssetId id,
    ModuleReader moduleReader,
    ScratchSpace scratchSpace,
    Map<String, String> environmentConstants,
    BarbackMode mode) {
  assert(id.extension == '.js');
  var outputCompleters = <AssetId, Completer<Asset>>{
    id: new Completer(),
  };
  var isDebug = mode == BarbackMode.DEBUG;
  if (isDebug) {
    outputCompleters[id.addExtension('.map')] = new Completer();
  }

  return _ensureComplete(outputCompleters, () async {
    var module = await moduleReader.moduleFor(id);
    var transitiveModuleDeps = await moduleReader.readTransitiveDeps(module);
    var linkedSummaryIds =
        transitiveModuleDeps.map((depId) => depId.linkedSummaryId).toSet();
    var allAssetIds = new Set<AssetId>()
      ..addAll(module.assetIds)
      ..addAll(linkedSummaryIds);
    await scratchSpace.ensureAssets(allAssetIds);
    var jsOutputFile = scratchSpace.fileFor(module.id.jsId);
    var sdk_summary = p.url.join(sdkDir.path, 'lib/_internal/ddc_sdk.sum');
    var request = new WorkRequest();
    request.arguments.addAll([
      '--dart-sdk-summary=$sdk_summary',
      '--modules=amd',
      '--dart-sdk=${sdkDir.path}',
      '--module-root=${scratchSpace.tempDir.path}',
      '--library-root=${p.dirname(jsOutputFile.path)}',
      '--summary-extension=${linkedSummaryExtension.substring(1)}',
      '--no-summarize',
      '-o',
      jsOutputFile.path,
    ]);

    if (isDebug) {
      request.arguments.addAll([
        '--source-map',
        '--source-map-comment',
        '--inline-source-map',
      ]);
    } else {
      request.arguments.add('--no-source-map');
    }

    // Add environment constants.
    environmentConstants.forEach((key, value) {
      request.arguments.add('-D$key=$value');
    });

    // Add all the linked summaries as summary inputs.
    for (var id in linkedSummaryIds) {
      request.arguments.addAll(['-s', scratchSpace.fileFor(id).path]);
    }

    // Add URL mappings for all the package: files to tell DartDevc where to
    // find them.
    for (var id in module.assetIds) {
      var uri = canonicalUriFor(id);
      if (uri.startsWith('package:')) {
        request.arguments
            .add('--url-mapping=$uri,${scratchSpace.fileFor(id).path}');
      }
    }
    // And finally add all the urls to compile, using the package: path for
    // files under lib and the full absolute path for other files.
    request.arguments.addAll(module.assetIds.map((id) {
      var uri = canonicalUriFor(id);
      if (uri.startsWith('package:')) {
        return uri;
      }
      return scratchSpace.fileFor(id).path;
    }));

    var response = await dartdevcDriver.doWork(request);

    // TODO(jakemac53): Fix the ddc worker mode so it always sends back a bad
    // status code if something failed. Today we just make sure there is an output
    // JS file to verify it was successful.
    if (response.exitCode != EXIT_CODE_OK || !jsOutputFile.existsSync()) {
      outputCompleters[module.id.jsId].completeError(
          new DartDevcCompilationException(module.id.jsId, response.output));
    } else {
      outputCompleters[module.id.jsId].complete(
          new Asset.fromBytes(module.id.jsId, jsOutputFile.readAsBytesSync()));
      if (isDebug) {
        var sourceMapFile = scratchSpace.fileFor(module.id.jsSourceMapId);
        outputCompleters[module.id.jsSourceMapId].complete(new Asset.fromBytes(
            module.id.jsSourceMapId, sourceMapFile.readAsBytesSync()));
      }
    }
  });
}

/// Copies the `dart_sdk.js` and `require.js` AMD files from the SDK into
/// [outputDir].
///
/// Returns a `Map<AssetId, Asset>` of the created assets.
Map<AssetId, Asset> copyDartDevcResources(String package, String outputDir) {
  var sdk = cli_util.getSdkDir();
  var outputs = <AssetId, Asset>{};

  // Copy the dart_sdk.js file for AMD into the output folder.
  var sdkJsOutputId =
      new AssetId(package, p.url.join(outputDir, 'dart_sdk.js'));
  var sdkAmdJsPath = p.url.join(sdk.path, 'lib/dev_compiler/amd/dart_sdk.js');
  outputs[sdkJsOutputId] =
      new Asset.fromFile(sdkJsOutputId, new File(sdkAmdJsPath));

  // Copy the require.js file for AMD into the output folder.
  var requireJsPath = p.url.join(sdk.path, 'lib/dev_compiler/amd/require.js');
  var requireJsOutputId =
      new AssetId(package, p.url.join(outputDir, 'require.js'));
  outputs[requireJsOutputId] =
      new Asset.fromFile(requireJsOutputId, new File(requireJsPath));

  return outputs;
}

/// Runs [fn], and then ensures that all [completers] are completed.
///
/// If an error is caught, then all [completers] that weren't completed are
/// completed with that error and stack trace.
///
/// If no error was caught then all [completers] that weren't completed are
/// completed with an [AssetNotFoundException].
///
/// Synchronously returns a `Map<AssetId, Future<Asset>` which is derived from
/// the original [completers].
Map<AssetId, Future<Asset>> _ensureComplete(
    Map<AssetId, Completer<Asset>> completers, Future fn()) {
  var futures = <AssetId, Future<Asset>>{};
  completers.forEach((k, v) => futures[k] = v.future);
  () async {
    try {
      await fn();
    } catch (e, s) {
      for (var completer in completers.values) {
        if (!completer.isCompleted) completer.completeError(e, s);
      }
    } finally {
      for (var id in completers.keys) {
        if (!completers[id].isCompleted) {
          completers[id].completeError(new AssetNotFoundException(id));
        }
      }
    }
  }();
  return futures;
}
