// 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/source/source.dart';
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);

  /// Return the `dart` URI representing the given [path] if the file is in
  /// this SDK, or `null` if the file is not in this SDK.
  Uri? pathToUri(String path);
}

/// 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<SdkLibraryImpl> 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 entry in _libraryMap.entries) {
      var uri = entry.key;
      var lib = entry.value;
      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:' [dartUri] 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;
  }
}

// Pre-existing name.
// ignore: camel_case_types
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) {
    var key = node.key as SimpleStringLiteral;
    var 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) {
            var value = (expression as StringLiteral).stringValue!;
            library.category = convertCategories(value);
          } 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
  late 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
  /// [shortName].
  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 => shortName.startsWith('dart:_');

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