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

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/src/generated/source.dart' show Source;
import 'package:pub_semver/pub_semver.dart';

/// A Dart SDK installed in a specified location.
abstract class DartSdk {
  /// The short name of the dart SDK 'async' library.
  static const String DART_ASYNC = "dart:async";

  /// The short name of the dart SDK 'core' library.
  static const String DART_CORE = "dart:core";

  /// The short name of the dart SDK 'html' library.
  static const String DART_HTML = "dart:html";

  /// The prefix shared by all dart library URIs.
  static const String DART_LIBRARY_PREFIX = "dart:";

  /// The version number that is returned when the real version number could not
  /// be determined.
  static const String DEFAULT_VERSION = "0";

  /// Return the content of the `allowed_experiments.json` file, or `null`
  /// if the file cannot be read, e.g. does not exist.
  String get allowedExperimentsJson;

  /// Return the language version of this SDK, or throws an exception.
  ///
  /// The language version has only major/minor components, the patch number
  /// is always zero, because the patch number does not change the language.
  Version get languageVersion;

  /// Return a list containing all of the libraries defined in this SDK.
  List<SdkLibrary> get sdkLibraries;

  /// Return the revision number of this SDK, or `"0"` if the revision number
  /// cannot be discovered.
  String get sdkVersion;

  /// Return a list containing the library URI's for the libraries defined in
  /// this SDK.
  List<String> get uris;

  /// Return a source representing the given 'file:' [uri] if the file is in
  /// this SDK, or `null` if the file is not in this SDK.
  Source fromFileUri(Uri uri);

  /// Return the library representing the library with the given 'dart:' [uri],
  /// or `null` if the given URI does not denote a library in this SDK.
  SdkLibrary getSdkLibrary(String uri);

  /// Return the source representing the library with the given 'dart:' [uri],
  /// or `null` if the given URI does not denote a library in this SDK.
  Source mapDartUri(String uri);
}

/// Manages the DartSdk's that have been created. Clients need to create
/// multiple SDKs when the analysis options associated with those SDK's contexts
/// will produce different analysis results.
class DartSdkManager {
  /// The absolute path to the directory containing the default SDK.
  final String defaultSdkDirectory;

  /// A table mapping (an encoding of) analysis options and SDK locations to the
  /// DartSdk from that location that has been configured with those options.
  Map<SdkDescription, DartSdk> sdkMap = HashMap<SdkDescription, DartSdk>();

  /// Initialize a newly created manager.
  DartSdkManager(this.defaultSdkDirectory, [@deprecated bool canUseSummaries]);

  /// Return any SDK that has been created, or `null` if no SDKs have been
  /// created.
  DartSdk get anySdk {
    if (sdkMap.isEmpty) {
      return null;
    }
    return sdkMap.values.first;
  }

  /// Return a list of the descriptors of the SDKs that are currently being
  /// managed.
  List<SdkDescription> get sdkDescriptors => sdkMap.keys.toList();

  /// Return the Dart SDK that is appropriate for the given SDK [description].
  /// If such an SDK has not yet been created, then the [ifAbsent] function will
  /// be invoked to create it.
  DartSdk getSdk(SdkDescription description, DartSdk Function() ifAbsent) {
    return sdkMap.putIfAbsent(description, ifAbsent);
  }
}

/// A map from Dart library URI's to the [SdkLibraryImpl] representing that
/// library.
class LibraryMap {
  /// A table mapping Dart library URI's to the library.
  final Map<String, SdkLibraryImpl> _libraryMap = <String, SdkLibraryImpl>{};

  /// Return a list containing all of the sdk libraries in this mapping.
  List<SdkLibrary> get sdkLibraries => List.from(_libraryMap.values);

  /// Return a list containing the library URI's for which a mapping is
  /// available.
  List<String> get uris => _libraryMap.keys.toList();

  /// Return info for debugging https://github.com/dart-lang/sdk/issues/35226.
  Map<String, Object> debugInfo() {
    var map = <String, Object>{};
    for (var uri in _libraryMap.keys) {
      var lib = _libraryMap[uri];
      map[uri] = <String, Object>{
        'path': lib.path,
        'shortName': lib.shortName,
      };
    }
    return map;
  }

  /// Return the library with the given 'dart:' [uri], or `null` if the URI does
  /// not map to a library.
  SdkLibrary getLibrary(String uri) => _libraryMap[uri];

  /// Set the library with the given 'dart:' [uri] to the given [library].
  void setLibrary(String dartUri, SdkLibraryImpl library) {
    _libraryMap[dartUri] = library;
  }

  /// Return the number of library URI's for which a mapping is available.
  int size() => _libraryMap.length;
}

/// A description of a [DartSdk].
class SdkDescription {
  /// The path of the SDK.
  final String path;

  SdkDescription(this.path);

  @override
  int get hashCode {
    return path.hashCode;
  }

  @override
  bool operator ==(Object other) {
    if (other is SdkDescription) {
      return other.path == path;
    }
    return false;
  }

  @override
  String toString() {
    return path;
  }
}

class SdkLibrariesReader_LibraryBuilder extends RecursiveAstVisitor<void> {
  /// The prefix added to the name of a library to form the URI used in code to
  /// reference the library.
  static const String _LIBRARY_PREFIX = "dart:";

  /// The name of the optional parameter used to indicate whether the library is
  /// an implementation library.
  static const String _IMPLEMENTATION = "implementation";

  /// The name of the optional parameter used to specify the path used when
  /// compiling for dart2js.
  static const String _DART2JS_PATH = "dart2jsPath";

  /// The name of the optional parameter used to indicate whether the library is
  /// documented.
  static const String _DOCUMENTED = "documented";

  /// The name of the optional parameter used to specify the category of the
  /// library.
  static const String _CATEGORIES = "categories";

  /// The name of the optional parameter used to specify the platforms on which
  /// the library can be used.
  static const String _PLATFORMS = "platforms";

  /// The value of the [PLATFORMS] parameter used to specify that the library
  /// can be used on the VM.
  static const String _VM_PLATFORM = "VM_PLATFORM";

  /// The library map that is populated by visiting the AST structure parsed
  /// from the contents of the libraries file.
  final LibraryMap _librariesMap = LibraryMap();

  /// Return the library map that was populated by visiting the AST structure
  /// parsed from the contents of the libraries file.
  LibraryMap get librariesMap => _librariesMap;

  // To be backwards-compatible the new categories field is translated to
  // an old approximation.
  String convertCategories(String categories) {
    switch (categories) {
      case "":
        return "Internal";
      case "Client":
        return "Client";
      case "Server":
        return "Server";
      case "Client,Server":
        return "Shared";
      case "Client,Server,Embedded":
        return "Shared";
    }
    return "Shared";
  }

  @override
  void visitMapLiteralEntry(MapLiteralEntry node) {
    String libraryName;
    Expression key = node.key;
    if (key is SimpleStringLiteral) {
      libraryName = "$_LIBRARY_PREFIX${key.value}";
    }
    Expression value = node.value;
    if (value is InstanceCreationExpression) {
      SdkLibraryImpl library = SdkLibraryImpl(libraryName);
      List<Expression> arguments = value.argumentList.arguments;
      for (Expression argument in arguments) {
        if (argument is SimpleStringLiteral) {
          library.path = argument.value;
        } else if (argument is NamedExpression) {
          String name = argument.name.label.name;
          Expression expression = argument.expression;
          if (name == _CATEGORIES) {
            library.category =
                convertCategories((expression as StringLiteral).stringValue);
          } else if (name == _IMPLEMENTATION) {
            library._implementation = (expression as BooleanLiteral).value;
          } else if (name == _DOCUMENTED) {
            library.documented = (expression as BooleanLiteral).value;
          } else if (name == _PLATFORMS) {
            if (expression is SimpleIdentifier) {
              String identifier = expression.name;
              if (identifier == _VM_PLATFORM) {
                library.setVmLibrary();
              } else {
                library.setDart2JsLibrary();
              }
            }
          } else if (name == _DART2JS_PATH) {
            if (expression is SimpleStringLiteral) {
              library.path = expression.value;
            }
          }
        }
      }
      _librariesMap.setLibrary(libraryName, library);
    }
  }
}

/// Represents a single library in the SDK
abstract class SdkLibrary {
  /// Return the name of the category containing the library.
  String get category;

  /// Return `true` if this library can be compiled to JavaScript by dart2js.
  bool get isDart2JsLibrary;

  /// Return `true` if the library is documented.
  bool get isDocumented;

  /// Return `true` if the library is an implementation library.
  bool get isImplementation;

  /// Return `true` if library is internal can be used only by other SDK
  /// libraries.
  bool get isInternal;

  /// Return `true` if this library can be used for both client and server.
  bool get isShared;

  /// Return `true` if this library can be run on the VM.
  bool get isVmLibrary;

  /// Return the path to the file defining the library. The path is relative to
  /// the `lib` directory within the SDK.
  String get path;

  /// Return the short name of the library. This is the URI of the library,
  /// including `dart:`.
  String get shortName;
}

/// The information known about a single library within the SDK.
class SdkLibraryImpl implements SdkLibrary {
  /// The bit mask used to access the bit representing the flag indicating
  /// whether a library is intended to work on the dart2js platform.
  static int DART2JS_PLATFORM = 1;

  /// The bit mask used to access the bit representing the flag indicating
  /// whether a library is intended to work on the VM platform.
  static int VM_PLATFORM = 2;

  @override
  final String shortName;

  /// The path to the file defining the library. The path is relative to the
  /// 'lib' directory within the SDK.
  @override
  String path;

  /// The name of the category containing the library. Unless otherwise
  /// specified in the libraries file all libraries are assumed to be shared
  /// between server and client.
  @override
  String category = "Shared";

  /// A flag indicating whether the library is documented.
  bool _documented = true;

  /// A flag indicating whether the library is an implementation library.
  bool _implementation = false;

  /// An encoding of which platforms this library is intended to work on.
  int _platforms = 0;

  /// Initialize a newly created library to represent the library with the given
  /// [name].
  SdkLibraryImpl(this.shortName);

  /// Set whether the library is documented.
  set documented(bool documented) {
    _documented = documented;
  }

  @override
  bool get isDart2JsLibrary => (_platforms & DART2JS_PLATFORM) != 0;

  @override
  bool get isDocumented => _documented;

  @override
  bool get isImplementation => _implementation;

  @override
  bool get isInternal => category == "Internal";

  @override
  bool get isShared => category == "Shared";

  @override
  bool get isVmLibrary => (_platforms & VM_PLATFORM) != 0;

  /// Record that this library can be compiled to JavaScript by dart2js.
  void setDart2JsLibrary() {
    _platforms |= DART2JS_PLATFORM;
  }

  /// Record that this library can be run on the VM.
  void setVmLibrary() {
    _platforms |= VM_PLATFORM;
  }
}
