// Copyright (c) 2017, 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:convert';

import '../interface/platform.dart';

/// Provides a mutable implementation of the [Platform] interface.
class FakePlatform extends Platform {
  /// Creates a new [FakePlatform] with the specified properties.
  ///
  /// Unspecified properties will *not* be assigned default values (they will
  /// remain `null`).
  FakePlatform({
    this.numberOfProcessors,
    this.pathSeparator,
    this.operatingSystem,
    this.localHostname,
    this.environment,
    this.executable,
    this.resolvedExecutable,
    this.script,
    this.executableArguments,
    this.packageRoot,
    this.packageConfig,
    this.version,
    this.ansiSupported,
  });

  /// Creates a new [FakePlatform] with properties whose initial values mirror
  /// the specified [platform].
  FakePlatform.fromPlatform(Platform platform)
      : numberOfProcessors = platform.numberOfProcessors,
        pathSeparator = platform.pathSeparator,
        operatingSystem = platform.operatingSystem,
        localHostname = platform.localHostname,
        environment = new Map<String, String>.from(platform.environment),
        executable = platform.executable,
        resolvedExecutable = platform.resolvedExecutable,
        script = platform.script,
        executableArguments =
            new List<String>.from(platform.executableArguments),
        packageRoot = platform.packageRoot,
        packageConfig = platform.packageConfig,
        version = platform.version,
        ansiSupported = platform.ansiSupported;

  /// Creates a new [FakePlatform] with properties extracted from the encoded
  /// JSON string.
  ///
  /// [json] must be a JSON string that matches the encoding produced by
  /// [toJson].
  factory FakePlatform.fromJson(String json) {
    Map<String, dynamic> map = new JsonDecoder().convert(json);
    return new FakePlatform(
      numberOfProcessors: map['numberOfProcessors'],
      pathSeparator: map['pathSeparator'],
      operatingSystem: map['operatingSystem'],
      localHostname: map['localHostname'],
      environment: map['environment'],
      executable: map['executable'],
      resolvedExecutable: map['resolvedExecutable'],
      script: Uri.parse(map['script']),
      executableArguments: map['executableArguments'],
      packageRoot: map['packageRoot'],
      packageConfig: map['packageConfig'],
      version: map['version'],
      ansiSupported: map['ansiSupported'],
    );
  }

  @override
  int numberOfProcessors;

  @override
  String pathSeparator;

  @override
  String operatingSystem;

  @override
  String localHostname;

  @override
  Map<String, String> environment;

  @override
  String executable;

  @override
  String resolvedExecutable;

  @override
  Uri script;

  @override
  List<String> executableArguments;

  @override
  String packageRoot;

  @override
  String packageConfig;

  @override
  String version;

  @override
  bool ansiSupported;
}
