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

// @dart = 2.6

part of dart.io;

/**
 * Information about the environment in which the current program is running.
 *
 * Platform provides information such as the operating system,
 * the hostname of the computer, the value of environment variables,
 * the path to the running program,
 * and so on.
 *
 * ## Get the URI to the current Dart script
 *
 * Use the [script] getter to get the URI to the currently running
 * Dart script.
 *
 *     import 'dart:io' show Platform;
 *
 *     void main() {
 *       // Get the URI of the script being run.
 *       var uri = Platform.script;
 *       // Convert the URI to a path.
 *       var path = uri.toFilePath();
 *     }
 *
 * ## Get the value of an environment variable
 *
 * The [environment] getter returns a the names and values of environment
 * variables in a [Map] that contains key-value pairs of strings. The Map is
 * unmodifiable. This sample shows how to get the value of the `PATH`
 * environment variable.
 *
 *     import 'dart:io' show Platform;
 *
 *     void main() {
 *       Map<String, String> envVars = Platform.environment;
 *       print(envVars['PATH']);
 *     }
 *
 * ## Determine the OS
 *
 * You can get the name of the operating system as a string with the
 * [operatingSystem] getter. You can also use one of the static boolean
 * getters: [isMacOS], [isLinux], and [isWindows].
 *
 *     import 'dart:io' show Platform, stdout;
 *
 *     void main() {
 *       // Get the operating system as a string.
 *       String os = Platform.operatingSystem;
 *       // Or, use a predicate getter.
 *       if (Platform.isMacOS) {
 *         print('is a Mac');
 *       } else {
 *         print('is not a Mac');
 *       }
 *     }
 *
 * ## Other resources
 *
 * [Dart by Example](https://www.dartlang.org/dart-by-example/#dart-io-and-command-line-apps)
 * provides additional task-oriented code samples that show how to use
 * various API from the [dart:io] library.
 */
class Platform {
  static final _numberOfProcessors = _Platform.numberOfProcessors;
  static final _pathSeparator = _Platform.pathSeparator;
  static final _operatingSystem = _Platform.operatingSystem;
  static final _operatingSystemVersion = _Platform.operatingSystemVersion;
  static final _localHostname = _Platform.localHostname;
  static final _version = _Platform.version;

  /**
   * The number of individual execution units of the machine.
   */
  static int get numberOfProcessors => _numberOfProcessors;

  /**
   * The path separator used by the operating system to separate
   * components in file paths.
   */
  static String get pathSeparator => _pathSeparator;

  /**
   * Get the name of the current locale.
   */
  static String get localeName => _Platform.localeName();

  /**
   * A string representing the operating system or platform.
   */
  static String get operatingSystem => _operatingSystem;

  /**
   * A string representing the version of the operating system or platform.
   */
  static String get operatingSystemVersion => _operatingSystemVersion;

  /**
   * The local hostname for the system.
   */
  static String get localHostname => _localHostname;

  /**
   * Whether the operating system is a version of
   * [Linux](https://en.wikipedia.org/wiki/Linux).
   *
   * This value is `false` if the operating system is a specialized
   * version of Linux that identifies itself by a different name,
   * for example Android (see [isAndroid]).
   */
  static final bool isLinux = (_operatingSystem == "linux");

  /**
   * Whether the operating system is a version of
   * [macOS](https://en.wikipedia.org/wiki/MacOS).
   */
  static final bool isMacOS = (_operatingSystem == "macos");

  /**
   * Whether the operating system is a version of
   * [Microsoft Windows](https://en.wikipedia.org/wiki/Microsoft_Windows).
   */
  static final bool isWindows = (_operatingSystem == "windows");

  /**
   * Whether the operating system is a version of
   * [Android](https://en.wikipedia.org/wiki/Android_%28operating_system%29).
   */
  static final bool isAndroid = (_operatingSystem == "android");

  /**
   * Whether the operating system is a version of
   * [iOS](https://en.wikipedia.org/wiki/IOS).
   */
  static final bool isIOS = (_operatingSystem == "ios");

  /**
   * Whether the operating system is a version of
   * [Fuchsia](https://en.wikipedia.org/wiki/Google_Fuchsia).
   */
  static final bool isFuchsia = (_operatingSystem == "fuchsia");

  /**
   * The environment for this process as a map from string key to string value.
   *
   * The map is unmodifiable,
   * and its content is retrieved from the operating system on its first use.
   *
   * Environment variables on Windows are case-insensitive,
   * so on Windows the map is case-insensitive and will convert
   * all keys to upper case.
   * On other platforms, keys can be distinguished by case.
   */
  static Map<String, String> get environment => _Platform.environment;

  /**
   * The path of the executable used to run the script in this isolate.
   *
   * The literal path used to identify the script.
   * This path might be relative or just be a name from which the executable
   * was found by searching the system path.
   *
   * Use [resolvedExecutable] to get an absolute path to the executable.
   */
  static String get executable => _Platform.executable;

  /**
   * The path of the executable used to run the script in this
   * isolate after it has been resolved by the OS.
   *
   * This is the absolute path, with all symlinks resolved, to the
   * executable used to run the script.
   */
  static String get resolvedExecutable => _Platform.resolvedExecutable;

  /**
   * The absolute URI of the script being run in this isolate.
   *
   * If the script argument on the command line is relative,
   * it is resolved to an absolute URI before fetching the script, and
   * that absolute URI is returned.
   *
   * URI resolution only does string manipulation on the script path, and this
   * may be different from the file system's path resolution behavior. For
   * example, a symbolic link immediately followed by '..' will not be
   * looked up.
   *
   * If the executable environment does not support [script],
   * the URI is empty.
   */
  static Uri get script => _Platform.script;

  /**
   * The flags passed to the executable used to run the script in this isolate.
   *
   * These are the command-line flags to the executable that precedes
   * the script name.
   * Provides a new list every time the value is read.
   */
  static List<String> get executableArguments => _Platform.executableArguments;

  /**
   * This returns `null`, as `packages/` directories are no longer supported.
   *
   */
  @Deprecated('packages/ directory resolution is not supported in Dart 2')
  static String get packageRoot => null; // TODO(mfairhurst): remove this

  /**
   * The `--packages` flag passed to the executable used to run the script
   * in this isolate.
   *
   * If present, it specifies a file describing how Dart packages are looked up.
   *
   * Is `null` if there is no `--packages` flag.
   */
  static String get packageConfig => _Platform.packageConfig;

  /**
   * The version of the current Dart runtime.
   *
   * The value is a [semantic versioning](http://semver.org)
   * string representing the version of the current Dart runtime,
   * possibly followed by whitespace and other version and
   * build details.
   */
  static String get version => _version;
}
