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

// VMOptions=--enable-isolate-groups --experimental-enable-isolate-groups-jit
// VMOptions=--no-enable-isolate-groups

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));
}

void f(reply) {
  reply.send({
    "Platform.executable": Platform.executable,
    "Platform.script": Platform.script,
    "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.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);
    if (match == null) {
      throw new FormatException();
    }
    var major = int.parse(match.group(1)!);
    // Major version.
    Expect.isTrue(major == 1 || major == 2);
    // Minor version.
    Expect.isTrue(int.parse(match.group(2)!) >= 0);
    // 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);
    }
  }

  checkInvalidVersion(String version) {
    try {
      checkValidVersion(version);
    } on FormatException {
      return;
    } on ExpectException {
      return;
    }
    Expect.testError("checkValidVersion accepts invalid version: $version");
  }

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

  // Sanity-checks for `checkValidVersion`.
  // Ensure we can match valid versions.
  checkValidVersion('1.9.0');
  checkValidVersion('2.0.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"'));
  // Reject some invalid versions.
  checkInvalidVersion('1.9');
  checkInvalidVersion('..');
  checkInvalidVersion('1..');
  checkInvalidVersion('1.9.');
  checkInvalidVersion('1.9.0-dev..');
  checkInvalidVersion('1.9.0-dev..0');
  checkInvalidVersion('1.9.0-dev.0.');
  checkInvalidVersion('1.9.0-dev.x.y');
  checkInvalidVersion('x');
  checkInvalidVersion('x.y.z');

  // Test current version.
  checkValidVersion(stripAdditionalInfo(Platform.version));
}

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