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

import "dart:async";
import "dart:io";
import "dart:isolate";

import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";

test() {
  Expect.isTrue(Platform.numberOfProcessors > 0);
  var os = Platform.operatingSystem;
  Expect.isTrue(os == "android" || os == "linux" || os == "macos" ||
      os == "windows");
  Expect.equals(Platform.isLinux, Platform.operatingSystem == "linux");
  Expect.equals(Platform.isMacOS, Platform.operatingSystem == "macos");
  Expect.equals(Platform.isWindows, Platform.operatingSystem == "windows");
  Expect.equals(Platform.isAndroid, Platform.operatingSystem == "android");
  var sep = Platform.pathSeparator;
  Expect.isTrue(sep == '/' || (os == 'windows' && sep == '\\'));
  var hostname = Platform.localHostname;
  Expect.isTrue(hostname is String && hostname != "");
  var environment = Platform.environment;
  Expect.isTrue(environment is Map<String, String>);
  if (!Platform.isWindows) {
    Expect.isTrue(Platform.executable.endsWith('dart'));
    Expect.isTrue(Platform.resolvedExecutable.endsWith('dart'));
  } else {
    Expect.isTrue(Platform.executable.endsWith('dart.exe'));
    Expect.isTrue(Platform.resolvedExecutable.endsWith('dart.exe'));
  }
  if (!Platform.isWindows) {
    Expect.isTrue(Platform.resolvedExecutable.startsWith('/'));
  } else {
    // This assumes that tests (both locally and on the bots) are
    // running off a location referred to by a drive letter. If a UNC
    // location is used or long names ("\\?\" prefix) is used this
    // needs to be fixed.
    Expect.equals(Platform.resolvedExecutable.substring(1, 3), ':\\');
  }
  // Move directory to be sure script is correct.
  var oldDir = Directory.current;
  Directory.current = Directory.current.parent;
  Expect.isTrue(Platform.script.path.
                endsWith('tests/standalone/io/platform_test.dart'));
  Expect.isTrue(Platform.script.toFilePath().startsWith(oldDir.path));
  // Restore dir.
  Directory.current = oldDir;
  var pkgRootString = Platform.packageRoot;
  if (pkgRootString != null) {
    Directory packageRoot = new Directory.fromUri(Uri.parse(pkgRootString));
    Expect.isTrue(packageRoot.existsSync());
    Expect.isTrue(new Directory("${packageRoot.path}/expect").existsSync());
    Expect.isTrue(Platform.executableArguments.any(
      (arg) {
        if (!arg.startsWith("--package-root=")) {
          return false;
        }
        // Cut out the '--package-root=' prefix.
        arg = arg.substring(15);
        return pkgRootString.contains(arg);
      }));
  }
}

void f(reply) {
  reply.send({"Platform.executable": Platform.executable,
              "Platform.script": Platform.script,
              "Platform.packageRoot": Platform.packageRoot,
              "Platform.executableArguments": Platform.executableArguments});
}

testIsolate() {
  asyncStart();
  ReceivePort port = new ReceivePort();
  var remote = Isolate.spawn(f, port.sendPort);
  port.first.then((results) {
    Expect.equals(Platform.executable, results["Platform.executable"]);

    Uri uri = results["Platform.script"];
    // SpawnFunction retains the script url of the parent which in this
    // case was a relative path.
    Expect.equals("file", uri.scheme);
    Expect.isTrue(uri.path.endsWith('tests/standalone/io/platform_test.dart'));
    Expect.equals(Platform.packageRoot, results["Platform.packageRoot"]);
    Expect.listEquals(Platform.executableArguments,
                      results["Platform.executableArguments"]);
    asyncEnd();
  });
}


testVersion() {
  checkValidVersion(String version) {
    RegExp re = new RegExp(r'(\d+)\.(\d+)\.(\d+)(-dev\.([^\.]*)\.([^\.]*))?');
    var match = re.firstMatch(version);
    Expect.isNotNull(match);
    // Major version.
    Expect.isTrue(int.parse(match.group(1)) == 1);
    // Minor version.
    Expect.isTrue(int.parse(match.group(2)) >= 9);
    // Patch version.
    Expect.isTrue(int.parse(match.group(3)) >= 0);
    // Dev
    if (match.group(4) != null) {
      // Dev prerelease minor version
      Expect.isTrue(int.parse(match.group(5)) >= 0);
      // Dev prerelease patch version
      Expect.isTrue(int.parse(match.group(6)) >= 0);
    }
  }

  String stripAdditionalInfo(String version) {
    var index = version.indexOf(' ');
    if (index == -1) return version;
    return version.substring(0, index);
  }

  // Ensure we can match valid versions.
  checkValidVersion('1.9.0');
  checkValidVersion('1.9.0-dev.0.0');
  checkValidVersion('1.9.0-edge');
  checkValidVersion('1.9.0-edge.r41234');
  // Check stripping of additional information.
  checkValidVersion(stripAdditionalInfo(
      '1.9.0-dev.1.2 (Wed Feb 25 02:22:19 2015) on "linux_ia32"'));
  // Test current version.
  checkValidVersion(stripAdditionalInfo(Platform.version));
  // Test some invalid versions.
  Expect.throws(() => checkValidVersion('1.9'));
  Expect.throws(() => checkValidVersion('2.0.0'));
  Expect.throws(() => checkValidVersion('..'));
  Expect.throws(() => checkValidVersion('1..'));
  Expect.throws(() => checkValidVersion('1.9.'));
  Expect.throws(() => checkValidVersion('1.9.0-dev..'));
  Expect.throws(() => checkValidVersion('1.9.0-dev..0'));
  Expect.throws(() => checkValidVersion('1.9.0-dev.0.'));
  Expect.throws(() => checkValidVersion('1.9.0-dev.x.y'));
  Expect.throws(() => checkValidVersion('x'));
  Expect.throws(() => checkValidVersion('x.y.z'));
}

main() {
  // This tests assumes paths relative to dart main directory
  Directory.current = Platform.script.resolve('../../..').toFilePath();
  test();
  testIsolate();
  testVersion();
}
