// Copyright (c) 2012, 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 command_lish;

import 'dart:io';
import 'dart:json';
import 'dart:uri';

import '../../pkg/args/lib/args.dart';
import '../../pkg/http/lib/http.dart' as http;
import '../../pkg/path/lib/path.dart' as path;
import 'directory_tree.dart';
import 'git.dart' as git;
import 'http.dart';
import 'io.dart';
import 'log.dart' as log;
import 'oauth2.dart' as oauth2;
import 'pub.dart';
import 'validator.dart';

/// Handles the `lish` and `publish` pub commands.
class LishCommand extends PubCommand {
  final description = "Publish the current package to pub.dartlang.org.";
  final usage = "pub publish [options]";
  final aliases = const ["lish", "lush"];

  ArgParser get commandParser {
    var parser = new ArgParser();
    // TODO(nweiz): Use HostedSource.defaultUrl as the default value once we use
    // dart:io for HTTPS requests.
    parser.addOption('server', defaultsTo: 'https://pub.dartlang.org',
        help: 'The package server to which to upload this package');
    return parser;
  }

  /// The URL of the server to which to upload the package.
  Uri get server => new Uri.fromString(commandOptions['server']);

  Future _publish(packageBytes) {
    var cloudStorageUrl;
    return oauth2.withClient(cache, (client) {
      // TODO(nweiz): Cloud Storage can provide an XML-formatted error. We
      // should report that error and exit.
      var newUri = server.resolve("/packages/versions/new.json");
      return client.get(newUri).chain((response) {
        var parameters = parseJsonResponse(response);

        var url = _expectField(parameters, 'url', response);
        if (url is! String) invalidServerResponse(response);
        cloudStorageUrl = new Uri.fromString(url);
        var request = new http.MultipartRequest('POST', cloudStorageUrl);

        var fields = _expectField(parameters, 'fields', response);
        if (fields is! Map) invalidServerResponse(response);
        fields.forEach((key, value) {
          if (value is! String) invalidServerResponse(response);
          request.fields[key] = value;
        });

        request.followRedirects = false;
        request.files.add(new http.MultipartFile.fromBytes(
            'file', packageBytes, filename: 'package.tar.gz'));
        return client.send(request);
      }).chain(http.Response.fromStream).transform((response) {
        var location = response.headers['location'];
        if (location == null) throw new PubHttpException(response);
        return location;
      }).chain((location) => client.get(location))
          .transform(handleJsonSuccess);
    }).transformException((e) {
      if (e is! PubHttpException) throw e;
      var url = e.response.request.url;
      if (url.toString() == cloudStorageUrl.toString()) {
        // TODO(nweiz): the response may have XML-formatted information about
        // the error. Try to parse that out once we have an easily-accessible
        // XML parser.
        throw 'Failed to upload the package.';
      } else if (url.origin == server.origin) {
        handleJsonError(e.response);
      }
    });
  }

  Future onRun() {
    var files;
    return _filesToPublish.transform((f) {
      files = f;
      log.fine('Archiving and publishing ${entrypoint.root}.');
      return createTarGz(files, baseDir: entrypoint.root.dir);
    }).chain(consumeInputStream).chain((packageBytes) {
      // Show the package contents so the user can verify they look OK.
      var package = entrypoint.root;
      log.message(
          'Publishing "${package.name}" ${package.version}:\n'
          '${generateTree(files)}');

      // Validate the package.
      return _validate().chain((_) => _publish(packageBytes));
    });
  }

  /// The basenames of files that are automatically excluded from archives.
  final _BLACKLISTED_FILES = const ['pubspec.lock'];

  /// The basenames of directories that are automatically excluded from
  /// archives.
  final _BLACKLISTED_DIRECTORIES = const ['packages'];

  /// Returns a list of files that should be included in the published package.
  /// If this is a Git repository, this will respect .gitignore; otherwise, it
  /// will return all non-hidden files.
  Future<List<String>> get _filesToPublish {
    var rootDir = entrypoint.root.dir;

    return Futures.wait([
      dirExists(join(rootDir, '.git')),
      git.isInstalled
    ]).chain((results) {
      if (results[0] && results[1]) {
        // List all files that aren't gitignored, including those not checked
        // in to Git.
        return git.run(["ls-files", "--cached", "--others",
                        "--exclude-standard"]);
      }

      return listDir(rootDir, recursive: true).chain((entries) {
        return Futures.wait(entries.map((entry) {
          return fileExists(entry).transform((isFile) {
            // Skip directories.
            if (!isFile) return null;

            // TODO(rnystrom): Making these relative will break archive
            // creation if the cwd is ever *not* the package root directory.
            // Should instead only make these relative right before generating
            // the tree display (which is what really needs them to be).
            // Make it relative to the package root.
            return relativeTo(entry, rootDir);
          });
        }));
      });
    }).transform((files) => files.filter((file) {
      if (file == null || _BLACKLISTED_FILES.contains(basename(file))) {
        return false;
      }

      return !splitPath(file).some(_BLACKLISTED_DIRECTORIES.contains);
    }));
  }

  /// Returns the value associated with [key] in [map]. Throws a user-friendly
  /// error if [map] doens't contain [key].
  _expectField(Map map, String key, http.Response response) {
    if (map.containsKey(key)) return map[key];
    invalidServerResponse(response);
  }

  /// Validates the package. Throws an exception if it's invalid.
  Future _validate() {
    return Validator.runAll(entrypoint).chain((pair) {
      var errors = pair.first;
      var warnings = pair.last;

      if (!errors.isEmpty) {
        throw "Sorry, your package is missing "
            "${(errors.length > 1) ? 'some requirements' : 'a requirement'} "
            "and can't be published yet.\nFor more information, see: "
            "http://pub.dartlang.org/doc/pub-lish.html.\n";
      }

      var message = 'Looks great! Are you ready to upload your package';

      if (!warnings.isEmpty) {
        var s = warnings.length == 1 ? '' : 's';
        message = "Package has ${warnings.length} warning$s. Upload anyway";
      }

      return confirm(message).transform((confirmed) {
        if (!confirmed) throw "Package upload canceled.";
      });
    });
  }
}
