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

/**
 * This file contains functionality for getting dart version numbers using
 * our standard version construction method. Systems that does not include this
 * file should emulate the structure for revision numbers that we have here.
 *
 * The version number of a dart build is constructed as follows:
 *   1. The major, minor, build and patch numbers are extracted from the VERSION
 *      file in the root directory. We call these MAJOR, MINOR, BUILD and PATCH.
 *   2. The svn revision number for the current checkout is extracted from the
 *      source control system that is used in the current checkout. We call this
 *      REVISION.
 *   3. If this is _not_ a official build, i.e., this is not build by our
 *      buildbot infrastructure, we extract the user-name of the logged in
 *      person from the operating system. We call this USERNAME.
 *   4. The version number is constructed as follows:
 *      MAJOR.MINOR.BUILD.PATCH_rREVISION_USERNAME
 */

library version;
import "dart:io";

/**
 * Generates version information for builds.
 */
class Version {
  String _versionFileName;
  String USERNAME;
  int REVISION;
  int MAJOR;
  int MINOR;
  int BUILD;
  int PATCH;

  Version(Path versionFile) {
    _versionFileName = versionFile.toNativePath();
  }

  /**
   * Get the version number for this specific build using the version info
   * from the VERSION file in the root directory and the revision info
   * from the source control system of the current checkout.
   */
  Future<String> getVersion() {
    File f = new File(_versionFileName);
    Completer c = new Completer();
    f.exists().then((existed) {
      if (!existed) {
        c.completeException("No VERSION file");
        return;
      }
      StringInputStream input = new StringInputStream(f.openInputStream());
      input.onLine = () {
        var line = input.readLine();
        if (line == null) {
          c.completeException(
              "VERSION input file seems to be in the wrong format");
          return;
        }
        var values = line.split(" ");
        if (values.length != 2) {
          c.completeException(
              "VERSION input file seems to be in the wrong format");
          return;
        }
        var number = 0;
        try {
          number = int.parse(values[1]);
        } catch (e) {
          c.completeException("Can't parse version numbers, not an int");
          return;
        }
        switch (values[0]) {
          case "MAJOR":
            MAJOR = number;
            break;
          case "MINOR":
            MINOR = number;
            break;
          case "BUILD":
            BUILD = number;
            break;
          case "PATCH":
            PATCH = number;
            break;
          default:
            c.completeException("Wrong format in VERSION file, line does not "
                                "contain one of {MAJOR, MINOR, BUILD, PATCH}");
            return;
        }
      };
      input.onClosed = () {
        // Only complete if we did not already complete with a failure.
        if (!c.future.isComplete) {
          getRevision().then((revision) {
            REVISION = revision;
            USERNAME = getUserName();
            var userNameString = "";
            if (USERNAME != '') userNameString = "_$USERNAME";
            var revisionString = "";
            if (revision != 0) revisionString = "_r$revision";
            c.complete(
                "$MAJOR.$MINOR.$BUILD.$PATCH$revisionString$userNameString");
            return;
          });
        }
      };
    });
    return c.future;
  }

  String getExecutableSuffix() {
    if (Platform.operatingSystem == 'windows') {
      return '.bat';
    }
    return '';
  }

  int getRevisionFromSvnInfo(String info) {
    if (info == null || info == '') return 0;
    var lines = info.split("\n");
    RegExp exp = const RegExp(r"Last Changed Rev: (\d*)");
    for (var line in lines) {
      if (exp.hasMatch(line)) {
        String revisionString = (exp.firstMatch(line).group(1));
        try {
          return int.parse(revisionString);
        } catch(e) {
          return 0;
        }
      }
    }
    return 0;
  }

  Future<int> getRevision() {
    if (repositoryType == RepositoryType.UNKNOWN) {
      return new Future.immediate(0);
    }
    var isSvn = repositoryType == RepositoryType.SVN;
    var command = isSvn ? "svn" : "git";
    command = "$command${getExecutableSuffix()}";
    var arguments = isSvn ? ["info"] : ["svn", "info"];
    ProcessOptions options = new ProcessOptions();
    // Run the command from the root to get the last changed revision for this
    // "branch". Since we have both trunk and bleeding edge in the same
    // repository and since we always build TOT we need this to get the
    // right version number.
    Path toolsDirectory = new Path.fromNative(_versionFileName).directoryPath;
    Path root = toolsDirectory.join(new Path(".."));
    options.workingDirectory = root.toNativePath();
    return Process.run(command, arguments, options).transform((result) {
      if (result.exitCode != 0) {
        return 0;
      }
      return getRevisionFromSvnInfo(result.stdout);
    });
  }

  bool isProductionBuild(String username) {
    return username == "chrome-bot";
  }

  String getUserName() {
    // TODO(ricow): Don't add this on the buildbot.
    var key = "USER";
    if (Platform.operatingSystem == 'windows') {
      key = "USERNAME";
    }
    if (!Platform.environment.containsKey(key)) return "";
    var username = Platform.environment[key];
    // If this is a production build, i.e., this is something we are shipping,
    // don't suffix  the version with the username.
    if (isProductionBuild(username)) return "";
    return username;
  }

  RepositoryType get repositoryType {
    if (new Directory(".svn").existsSync()) return RepositoryType.SVN;
    if (new Directory(".git").existsSync()) return RepositoryType.GIT;
    return RepositoryType.UNKNOWN;
  }
}

class RepositoryType {
  static final RepositoryType SVN = const RepositoryType("SVN");
  static final RepositoryType GIT = const RepositoryType("GIT");
  static final RepositoryType UNKNOWN = const RepositoryType("UNKNOWN");

  const RepositoryType(String this.name);

  static RepositoryType guessType() {
    if (new Directory(".svn").existsSync()) return RepositoryType.SVN;
    if (new Directory(".git").existsSync()) return RepositoryType.GIT;
    return RepositoryType.UNKNOWN;
  }

  String toString() => name;

  final String name;
}
