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

/**
 * 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:async";
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();

    var wasCompletedWithError = false;
    completeError(String msg) {
      if (!wasCompletedWithError) {
        c.completeError(msg);
        wasCompletedWithError = true;
      }
    }
    f.exists().then((existed) {
      if (!existed) {
        completeError("No VERSION file");
        return;
      }
      Stream<String> stream =
          f.openRead().transform(new StringDecoder())
                      .transform(new LineTransformer());
      stream.listen((String line) {
        if (line == null) {
          completeError(
              "VERSION input file seems to be in the wrong format");
          return;
        }
        var values = line.split(" ");
        if (values.length != 2) {
          completeError(
              "VERSION input file seems to be in the wrong format");
          return;
        }
        var number = 0;
        try {
          number = int.parse(values[1]);
        } catch (e) {
          completeError("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:
            completeError("Wrong format in VERSION file, line does not "
                            "contain one of {MAJOR, MINOR, BUILD, PATCH}");
            return;
        }
      },
      onDone: () {
        // Only complete if we did not already complete with a failure.
        if (!wasCompletedWithError) {
          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 = new 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.value(0);
    }
    var isSvn = repositoryType == RepositoryType.SVN;
    var command = isSvn ? "svn" : "git";
    command = "$command${getExecutableSuffix()}";
    var arguments = isSvn ? ["info"] : ["svn", "info"];
    // 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(_versionFileName).directoryPath;
    Path root = toolsDirectory.join(new Path(".."));
    var workingDirectory = root.toNativePath();
    return Process.run(command,
                       arguments,
                       workingDirectory: workingDirectory).then((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 {
    bool isWindows = Platform.operatingSystem == 'windows';
    bool hasDirectory(path, name) {
      return new Directory.fromPath(path.append(name)).existsSync();
    }
    bool isFileSystemRoot(absolutePath) {
      if (isWindows) {
        return "${absolutePath.directoryPath}" == '/';
      }
      return "$absolutePath" == '/';
    }

    var currentPath = new Path(Directory.current.path);
    while (true) {
      if (hasDirectory(currentPath, '.svn')) {
        return RepositoryType.SVN;
      } else if (hasDirectory(currentPath, '.git')) {
        return RepositoryType.GIT;
      }
      if (isFileSystemRoot(currentPath)) {
        break;
      }
      currentPath = currentPath.directoryPath;
    }
    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;
}
