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

import 'dart:io';
import 'dart:async' hide TimeoutException;

import 'package:args/args.dart';
import 'package:path/path.dart' as path;
import 'package:stack_trace/stack_trace.dart';

import 'command/build.dart';
import 'command/cache.dart';
import 'command/get.dart';
import 'command/help.dart';
import 'command/lish.dart';
import 'command/list_package_dirs.dart';
import 'command/serve.dart';
import 'command/upgrade.dart';
import 'command/uploader.dart';
import 'command/version.dart';
import 'entrypoint.dart';
import 'exit_codes.dart' as exit_codes;
import 'http.dart';
import 'io.dart';
import 'log.dart' as log;
import 'system_cache.dart';
import 'utils.dart';

/// The base class for commands for the pub executable.
abstract class PubCommand {
  /// The commands that pub understands.
  static final Map<String, PubCommand> commands = _initCommands();

  SystemCache cache;

  /// The parsed options for this command.
  ArgResults commandOptions;

  Entrypoint entrypoint;

  /// A one-line description of this command.
  String get description;

  /// If the command is undocumented and should not appear in command listings,
  /// this will be `true`.
  bool get hidden => false;

  /// How to invoke this command (e.g. `"pub get [package]"`).
  String get usage;

  /// Whether or not this command requires [entrypoint] to be defined. If false,
  /// pub won't look for a pubspec and [entrypoint] will be null when the
  /// command runs.
  bool get requiresEntrypoint => true;

  /// Whether or not this command takes arguments in addition to options. If
  /// false, pub will exit with an error if arguments are provided.
  bool get takesArguments => false;

  /// Alternate names for this command. These names won't be used in the
  /// documentation, but they will work when invoked on the command line.
  final aliases = const <String>[];

  /// The [ArgParser] for this command.
  final commandParser = new ArgParser();

  /// Override this to use offline-only sources instead of hitting the network.
  /// This will only be called before the [SystemCache] is created. After that,
  /// it has no effect.
  bool get isOffline => false;

  PubCommand() {
    // Allow "--help" after a command to get command help.
    commandParser.addFlag('help', abbr: 'h', negatable: false,
        help: 'Print usage information for this command.');
  }

  void run(String cacheDir, ArgResults options, List<String> arguments) {
    commandOptions = options.command;

    if (commandOptions['help']) {
      this.printUsage();
      return;
    }

    cache = new SystemCache.withSources(cacheDir, isOffline: isOffline);

    handleError(error, trace) {
      // This is basically the top-level exception handler so that we don't
      // spew a stack trace on our users.
      var message;

      log.error(getErrorMessage(error));

      if (trace != null) {
        if (options['trace'] || !isUserFacingException(error)) {
          log.error(new Trace.from(trace).terse);
        } else {
          log.fine(new Trace.from(trace).terse);
        }
      }

      if (error is ApplicationException && error.innerError != null) {
        var message = "Wrapped exception: ${error.innerError}";
        if (error.innerTrace != null) message = "$message\n${error.innerTrace}";
        log.fine(message);
      }

      if (options['trace']) {
        log.dumpTranscript();
      } else if (!isUserFacingException(error)) {
        log.error("""
This is an unexpected error. Please run

    pub --trace ${arguments.map((arg) => "'$arg'").join(' ')}

and include the results in a bug report on http://dartbug.com/new.
""");
      }

      return flushThenExit(_chooseExitCode(error));
    }

    new Future.sync(() {
      // Make sure there aren't unexpected arguments.
      if (!takesArguments && commandOptions.rest.isNotEmpty) {
        log.error('Command "${commandOptions.name}" does not take any '
                  'arguments.');
        this.printUsage();
        return flushThenExit(exit_codes.USAGE);
      }

      if (requiresEntrypoint) {
        // TODO(rnystrom): Will eventually need better logic to walk up
        // subdirectories until we hit one that looks package-like. For now,
        // just assume the cwd is it.
        entrypoint = new Entrypoint(path.current, cache);
      }

      var commandFuture = onRun();
      if (commandFuture == null) return true;

      return commandFuture;
    }).whenComplete(() => cache.deleteTempDir())
        .catchError(handleError)
        .then((_) {
      // Explicitly exit on success to ensure that any dangling dart:io handles
      // don't cause the process to never terminate.
      return flushThenExit(0);
    });
  }

  /// Override this to perform the specific command. Return a future that
  /// completes when the command is done or fails if the command fails. If the
  /// command is synchronous, it may return `null`.
  Future onRun();

  /// Displays usage information for this command.
  void printUsage([String description]) {
    if (description == null) description = this.description;

    var buffer = new StringBuffer();
    buffer.write('$description\n\nUsage: $usage');

    var commandUsage = commandParser.getUsage();
    if (!commandUsage.isEmpty) {
      buffer.write('\n');
      buffer.write(commandUsage);
    }

    log.message(buffer.toString());
  }

  /// Returns the appropriate exit code for [exception], falling back on 1 if no
  /// appropriate exit code could be found.
  int _chooseExitCode(exception) {
    if (exception is HttpException || exception is HttpException ||
        exception is SocketException || exception is PubHttpException) {
      return exit_codes.UNAVAILABLE;
    } else if (exception is FormatException) {
      return exit_codes.DATA;
    } else {
      return 1;
    }
  }
}

_initCommands() {
  var commands = {
    'build': new BuildCommand(),
    'cache': new CacheCommand(),
    'get': new GetCommand(),
    'help': new HelpCommand(),
    'list-package-dirs': new ListPackageDirsCommand(),
    'publish': new LishCommand(),
    'serve': new ServeCommand(),
    'upgrade': new UpgradeCommand(),
    'uploader': new UploaderCommand(),
    'version': new VersionCommand()
  };

  for (var command in commands.values.toList()) {
    for (var alias in command.aliases) {
      commands[alias] = command;
    }
  }

  return commands;
}
