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

library pub.command.build;

import 'dart:async';

import 'package:barback/barback.dart';
import 'package:path/path.dart' as path;

import '../barback/dart2js_transformer.dart';
import '../barback/dart_forwarding_transformer.dart';
import '../barback.dart' as barback;
import '../command.dart';
import '../exit_codes.dart' as exit_codes;
import '../io.dart';
import '../log.dart' as log;
import '../utils.dart';

final _arrow = getSpecial('\u2192', '=>');

/// Handles the `build` pub command.
class BuildCommand extends PubCommand {
  String get description =>
      "Copy and compile all Dart entrypoints in the 'web' directory.";
  String get usage => "pub build [options]";
  List<String> get aliases => const ["deploy", "settle-up"];

  // TODO(nweiz): make these configurable.
  /// The path to the source directory of the application.
  String get source => path.join(entrypoint.root.dir, 'web');

  /// The path to the application's build output directory.
  String get target => path.join(entrypoint.root.dir, 'build');

  /// The build mode.
  BarbackMode get mode => new BarbackMode(commandOptions['mode']);

  BuildCommand() {
    commandParser.addOption('mode', defaultsTo: BarbackMode.RELEASE.toString(),
        help: 'Mode to run transformers in.');
  }

  Future onRun() {
    if (!dirExists(source)) {
      throw new ApplicationException('There is no "$source" directory.');
    }

    cleanDir(target);

    var dart2jsTransformer;
    var builtFiles = 0;

    return entrypoint.loadPackageGraph().then((graph) {
      dart2jsTransformer = new Dart2JSTransformer(graph, mode);
      var builtInTransformers = [
        dart2jsTransformer,
        new DartForwardingTransformer(mode)
      ];

      // Since this server will only be hit by the transformer loader and isn't
      // user-facing, just use an IPv4 address to avoid a weird bug on the
      // OS X buildbots.
      // TODO(rnystrom): Allow specifying mode.
      return barback.createServer("127.0.0.1", 0, graph, mode,
          builtInTransformers: builtInTransformers,
          watcher: barback.WatcherType.NONE);
    }).then((server) {
      // Show in-progress errors, but not results. Those get handled implicitly
      // by getAllAssets().
      server.barback.errors.listen((error) {
        log.error(log.red("Build error:\n$error"));
      });

      return log.progress("Building ${entrypoint.root.name}",
          () => server.barback.getAllAssets());
    }).then((assets) {
      return Future.wait(assets.map((asset) {
        // In release mode, strip out .dart files since all relevant ones have
        // been compiled to JavaScript already.
        if (mode == BarbackMode.RELEASE && asset.id.extension == ".dart") {
          return new Future.value();
        }

        builtFiles++;

        // Figure out the output directory for the asset, which is the same
        // as the path pub serve would use to serve it.
        var relativeUrl = barback.idtoUrlPath(entrypoint.root.name, asset.id);

        // Remove the leading "/".
        relativeUrl = relativeUrl.substring(1);

        var relativePath = path.fromUri(new Uri(path: relativeUrl));
        var destPath = path.join(target, relativePath);

        ensureDir(path.dirname(destPath));
        // TODO(rnystrom): Should we display this to the user?
        return createFileFromStream(asset.read(), destPath);
      })).then((_) {
        builtFiles += _copyBrowserJsFiles(dart2jsTransformer.entrypoints);
        log.message("Built $builtFiles ${pluralize('file', builtFiles)}!");
      });
    }).catchError((error) {
      // If [getAllAssets()] throws a BarbackException, the error has already
      // been reported.
      if (error is! BarbackException) throw error;

      log.error(log.red("Build failed."));
      return flushThenExit(exit_codes.DATA);
    });
  }

  /// If this package depends directly on the `browser` package, this ensures
  /// that the JavaScript bootstrap files are copied into `packages/browser/`
  /// directories next to each entrypoint in [entrypoints].
  ///
  /// Returns the number of files it copied.
  int _copyBrowserJsFiles(Iterable<AssetId> entrypoints) {
    // Must depend on the browser package.
    if (!entrypoint.root.dependencies.any(
        (dep) => dep.name == 'browser' && dep.source == 'hosted')) {
      return 0;
    }

    // Get all of the directories that contain Dart entrypoints.
    var entrypointDirs = entrypoints
        .map((id) => path.url.split(id.path))
        .map((parts) => parts.skip(1)) // Remove "web/".
        .map((relative) => path.dirname(path.joinAll(relative)))
        .toSet();

    for (var dir in entrypointDirs) {
      // TODO(nweiz): we should put browser JS files next to any HTML file
      // rather than any entrypoint. An HTML file could import an entrypoint
      // that's not adjacent.
      _addBrowserJs(dir, "dart");
      _addBrowserJs(dir, "interop");
    }

    return entrypointDirs.length * 2;
  }

  // TODO(nweiz): do something more principled when issue 6101 is fixed.
  /// Ensures that the [name].js file is copied into [directory] in [target],
  /// under `packages/browser/`.
  void _addBrowserJs(String directory, String name) {
    var jsPath = path.join(
        target, directory, 'packages', 'browser', '$name.js');
    ensureDir(path.dirname(jsPath));
    copyFile(path.join(entrypoint.packagesDir, 'browser', '$name.js'), jsPath);
  }
}
