// Copyright (c) 2025, 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.

/// Generates the file `api.txt`, which describes a package's public API.
library;

import 'dart:collection';

import 'package:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer_utilities/tools.dart';
import 'package:collection/collection.dart';
import 'package:path/path.dart';

/// Computes a list of all targets generated by this code generator for a given
/// package.
List<GeneratedContent> allTargetsForPackage(String pkgName) => [
  GeneratedFile('$pkgName/api.txt', (pkgRoot) async {
    var provider = PhysicalResourceProvider.INSTANCE;
    var collection = AnalysisContextCollection(
      includedPaths: [join(pkgRoot, pkgName)],
      resourceProvider: provider,
    );
    // Use `.single` to make sure that `collection` just contains a single
    // context. This ensures that `publicApi.build` will see all the files in
    // the package.
    var context = collection.contexts.single;
    var publicApi = ApiDescription(pkgName);
    var stringBuffer = StringBuffer();
    _printNodes(stringBuffer, await publicApi.build(context));
    return stringBuffer.toString();
  }),
];

/// Outputs the contents of [nodes] to [sink], prepending [prefix] to every
/// line.
void _printNodes<SortKey extends Comparable<SortKey>>(
  StringSink sink,
  List<(SortKey, Node)> nodes, {
  String prefix = '',
}) {
  for (var entry in nodes.sortedBy((n) => n.$1)) {
    var node = entry.$2;
    sink.writeln('$prefix${node.text.join()}');
    node.printChildren(sink, prefix: '$prefix  ');
  }
}

/// Data structure keeping track of a package's API while walking it to produce
/// `api.txt`.
class ApiDescription {
  final String _pkgName;

  /// Top level elements that have already had their child elements dumped.
  ///
  /// If an element is seen again in a different library, it will be followed
  /// with `(see above)` (rather than having its child elements dumped twice).
  final _dumpedTopLevelElements = <Element>{};

  /// Top level elements that have been referenced so far and haven't yet been
  /// processed by [build].
  ///
  /// This is used to ensure that all elements referred to by the public API
  /// (e.g., by being mentioned in the type of an API element) also show up in
  /// the output.
  final _potentiallyDanglingReferences = Queue<Element>();

  final _uniqueNamer = UniqueNamer();

  /// Cache of values returned by [_getOrComputeImmediateSubinterfaceMap], to
  /// avoid unnecessary recomputation.
  final _immediateSubinterfaceCache =
      <LibraryElement, Map<ClassElement, Set<InterfaceElement>>>{};

  ApiDescription(String pkgName) : _pkgName = pkgName;

  /// Builds a list of [Node] objects representing all the libraries that are
  /// relevant to the package's public API.
  ///
  /// This includes libraries that are in the package's public API as well as
  /// libraries that are referenced by the package's public API (either by being
  /// re-exported as part of the package's public API, or by being used as part
  /// of the type of something in the public API).
  ///
  /// Each library node is pared with a [UriSortKey] indicating the order in
  /// which the nodes should be output.
  Future<List<(UriSortKey, Node)>> build(AnalysisContext context) async {
    var nodes = <Uri, Node<MemberSortKey>>{};
    for (var file in context.contextRoot.analyzedFiles().sorted()) {
      if (!file.endsWith('.dart')) continue;
      var fileResult = context.currentSession.getFile(file) as FileResult;
      var uri = fileResult.uri;
      if (fileResult.isLibrary && uri.isInPublicLibOf(_pkgName)) {
        var resolvedLibraryResult =
            (await context.currentSession.getResolvedLibrary(file))
                as ResolvedLibraryResult;
        var node = nodes[uri] = Node<MemberSortKey>();
        _dumpLibrary(resolvedLibraryResult.element, node);
      }
    }
    // Then dump anything referenced by public libraries.
    while (_potentiallyDanglingReferences.isNotEmpty) {
      var element = _potentiallyDanglingReferences.removeFirst();
      if (!_dumpedTopLevelElements.add(element)) continue;
      var containingLibraryUri = element.library!.uri;
      var childNode =
          Node<MemberSortKey>()..text.add(_uniqueNamer.name(element));
      _dumpElement(element, childNode);
      (nodes[containingLibraryUri] ??=
              Node<MemberSortKey>()..text.add('$containingLibraryUri:'))
          .childNodes
          .add((MemberSortKey(element), childNode));
    }
    return [
      for (var entry in nodes.entries)
        (UriSortKey(entry.key, _pkgName), entry.value),
    ];
  }

  /// Creates a list of objects which, when their string representations are
  /// concatenated, describes [type].
  ///
  /// The reason we use this method rather than [DartType.toString] is to make
  /// sure that (a) every element mentioned by the type is added to
  /// [_potentiallyDanglingReferences], and (b) if an ambiguous name is used,
  /// the ambiguity will be taken care of by [_uniqueNamer].
  List<Object?> _describeType(DartType type) {
    var suffix = switch (type.nullabilitySuffix) {
      NullabilitySuffix.none => '',
      NullabilitySuffix.star => '*',
      NullabilitySuffix.question => '?',
    };
    switch (type) {
      case DynamicType():
        return ['dynamic'];
      case FunctionType(
        :var returnType,
        :var typeParameters,
        :var formalParameters,
      ):
        var params = <List<Object?>>[];
        var optionalParams = <List<Object?>>[];
        var namedParams = <String, List<Object?>>{};
        for (var formalParameter in formalParameters) {
          if (formalParameter.isNamed) {
            namedParams[formalParameter.name!] = [
              if (formalParameter.isDeprecated) 'deprecated ',
              if (formalParameter.isRequired) 'required ',
              ..._describeType(formalParameter.type),
            ];
          } else if (formalParameter.isOptional) {
            optionalParams.add([
              if (formalParameter.isDeprecated) 'deprecated ',
              ..._describeType(formalParameter.type),
            ]);
          } else {
            params.add([
              if (formalParameter.isDeprecated) 'deprecated ',
              ..._describeType(formalParameter.type),
            ]);
          }
        }
        if (optionalParams.isNotEmpty) {
          params.add(optionalParams.separate(prefix: '[', suffix: ']'));
        }
        if (namedParams.isNotEmpty) {
          params.add(
            namedParams.entries
                .sortedBy((e) => e.key)
                .map((e) => [...e.value, ' ${e.key}'])
                .separate(prefix: '{', suffix: '}'),
          );
        }
        return <Object?>[
          ..._describeType(returnType),
          ' Function',
          if (typeParameters.isNotEmpty)
            ...typeParameters
                .map(_describeTypeParameter)
                .separate(prefix: '<', suffix: '>'),
          '(',
          ...params.separate(),
          ')',
          suffix,
        ];
      case InterfaceType(:var element, :var typeArguments):
        _potentiallyDanglingReferences.addLast(element);
        return [
          _uniqueNamer.name(element),
          if (typeArguments.isNotEmpty)
            ...typeArguments
                .map(_describeType)
                .separate(prefix: '<', suffix: '>'),
          suffix,
        ];
      case RecordType(:var positionalFields, :var namedFields):
        if (positionalFields.length == 1 && namedFields.isEmpty) {
          return [
            '(',
            ..._describeType(positionalFields[0].type),
            ',)',
            suffix,
          ];
        }
        return [
          ...[
            for (var positionalField in positionalFields)
              _describeType(positionalField.type),
            if (namedFields.isNotEmpty)
              namedFields
                  .sortedBy((f) => f.name)
                  .map((f) => [..._describeType(f.type), ' ', f.name])
                  .separate(prefix: '{', suffix: '}'),
          ].separate(prefix: '(', suffix: ')'),
          suffix,
        ];
      case TypeParameterType(:var element):
        return [element.name!, suffix];
      case VoidType():
        return ['void'];
      case dynamic(:var runtimeType):
        throw UnimplementedError('Unexpected type: $runtimeType');
    }
  }

  /// Creates a list of objects which, when their string representations are
  /// concatenated, describes [typeParameter].
  List<Object?> _describeTypeParameter(TypeParameterElement typeParameter) {
    return [
      typeParameter.name!,
      if (typeParameter.bound case var bound?) ...[
        ' extends ',
        ..._describeType(bound),
      ],
    ];
  }

  /// Appends information to [node] describing [element].
  void _dumpElement(Element element, Node<MemberSortKey> node) {
    var enclosingElement = element.enclosingElement;
    if (enclosingElement is LibraryElement &&
        !element.isInPublicApiOf(_pkgName)) {
      if (!enclosingElement.uri.isIn(_pkgName)) {
        node.text.add(' (referenced)');
      } else {
        node.text.add(' (non-public)');
      }
      return;
    }
    var parentheticals = <List<Object?>>[];
    switch (element) {
      case TypeAliasElement(:var aliasedType, :var typeParameters):
        List<Object?> description = ['type alias'];
        if (typeParameters.isNotEmpty) {
          description.addAll(
            typeParameters
                .map(_describeTypeParameter)
                .separate(prefix: '<', suffix: '>'),
          );
        }
        description.addAll([' for ', ..._describeType(aliasedType)]);
        parentheticals.add(description);
      case InstanceElement():
        switch (element) {
          case InterfaceElement(
            :var typeParameters,
            :var supertype,
            :var interfaces,
          ):
            List<Object?> instanceDescription = [
              switch (element) {
                ClassElement() => 'class',
                EnumElement() => 'enum',
                MixinElement() => 'mixin',
                dynamic(:var runtimeType) => 'TODO: $runtimeType',
              },
            ];
            if (typeParameters.isNotEmpty) {
              instanceDescription.addAll(
                typeParameters
                    .map(_describeTypeParameter)
                    .separate(prefix: '<', suffix: '>'),
              );
            }
            if (element is! EnumElement && supertype != null) {
              instanceDescription.addAll([
                ' extends ',
                ..._describeType(supertype),
              ]);
            }
            if (element is MixinElement &&
                element.superclassConstraints.isNotEmpty) {
              instanceDescription.addAll(
                element.superclassConstraints
                    .map(_describeType)
                    .separate(prefix: ' on '),
              );
            }
            if (interfaces.isNotEmpty) {
              instanceDescription.addAll(
                interfaces.map(_describeType).separate(prefix: ' implements '),
              );
            }
            parentheticals.add(instanceDescription);
            if (element is ClassElement && element.isSealed) {
              var parenthetical = <Object>['sealed'];
              parentheticals.add(parenthetical);
              if (_getOrComputeImmediateSubinterfaceMap(
                    element.library,
                  )[element]
                  case var subinterfaces?) {
                parenthetical.add(' (immediate subtypes: ');
                // Note: it's tempting to just do
                // `subinterfaces.map(_uniqueNamer.name).join(', ')`, but that
                // won't work, because the names returned by
                // `UniqueName.toString()` aren't finalized until we've visited
                // the entire API and seen if there are class names that need to
                // be disambiguated. So we accumulate the `UniqueName` objects
                // into the `parenthetical` list and rely on `printNodes`
                // converting everything to a string when the final API
                // description is being output.
                var commaNeeded = false;
                for (var subinterface in subinterfaces) {
                  if (commaNeeded) {
                    parenthetical.add(', ');
                  } else {
                    commaNeeded = true;
                  }
                  parenthetical.add(_uniqueNamer.name(subinterface));
                }
                parenthetical.add(')');
              }
            }
          case ExtensionElement(:var extendedType):
            parentheticals.add([
              'extension on ',
              ..._describeType(extendedType),
            ]);
          case dynamic(:var runtimeType):
            throw UnimplementedError('Unexpected element: $runtimeType');
        }
        for (var member in element.children.sortedBy((m) => m.name ?? '')) {
          if (member.name case var name? when name.startsWith('_')) {
            // Ignore private members
            continue;
          }
          if (member is FieldElement) {
            // Ignore fields; we care about the getters and setters they induce.
            continue;
          }
          if (member is ConstructorElement &&
              element is ClassElement &&
              element.isAbstract &&
              (element.isFinal || element.isInterface || element.isSealed)) {
            // The class can't be constructed from outside of the library that
            // declares it, so its constructors aren't part of the public API.
            continue;
          }
          if (member is ConstructorElement && element is EnumElement) {
            // Enum constructors can't be called from outside the enum itself,
            // so they aren't part of the public API.
            continue;
          }
          var childNode = Node<MemberSortKey>();
          childNode.text.add(member.apiName);
          _dumpElement(member, childNode);
          node.childNodes.add((MemberSortKey(member), childNode));
        }
      case TopLevelFunctionElement(:var type):
        parentheticals.add(['function: ', ..._describeType(type)]);
      case ExecutableElement(:var isStatic):
        String maybeStatic = isStatic ? 'static ' : '';
        switch (element) {
          case GetterElement(:var type):
            parentheticals.add([
              '${maybeStatic}getter: ',
              ..._describeType(type.returnType),
            ]);
          case SetterElement(:var type):
            parentheticals.add([
              '${maybeStatic}setter: ',
              ..._describeType(type.formalParameters.single.type),
            ]);
          case MethodElement(:var type):
            parentheticals.add([
              '${maybeStatic}method: ',
              ..._describeType(type),
            ]);
          case ConstructorElement(:var type):
            parentheticals.add(['constructor: ', ..._describeType(type)]);
          case dynamic(:var runtimeType):
            throw UnimplementedError('Unexpected element: $runtimeType');
        }
      case dynamic(:var runtimeType):
        throw UnimplementedError('Unexpected element: $runtimeType');
    }

    if (element.metadata.hasDeprecated) {
      parentheticals.add(['deprecated']);
    }
    if (element.metadata.hasExperimental) {
      parentheticals.add(['experimental']);
    }

    if (parentheticals.isNotEmpty) {
      node.text.addAll(parentheticals.separate(prefix: ' (', suffix: ')'));
    }
    if (node.childNodes.isNotEmpty) {
      node.text.add(':');
    }
  }

  /// Appends information to [node] describing [element].
  void _dumpLibrary(LibraryElement library, Node<MemberSortKey> node) {
    var uri = library.uri;
    node.text.addAll([uri, ':']);
    var definedNames = library.exportNamespace.definedNames2;
    for (var key in definedNames.keys.sorted()) {
      var element = definedNames[key]!;
      var childNode =
          Node<MemberSortKey>()..text.add(_uniqueNamer.name(element));
      if (!_dumpedTopLevelElements.add(element)) {
        childNode.text.add(' (see above)');
      } else {
        _dumpElement(element, childNode);
      }
      node.childNodes.add((MemberSortKey(element), childNode));
    }
  }

  /// Returns a map from each sealed class in [library] to the set of its
  /// immediate sub-interfaces.
  ///
  /// If this method has been called before with the same [library], a cached
  /// map is returned from [_immediateSubinterfaceCache]. Otherwise a fresh map
  /// is computed.
  Map<ClassElement, Set<InterfaceElement>>
  _getOrComputeImmediateSubinterfaceMap(LibraryElement library) {
    if (_immediateSubinterfaceCache[library] case var m?) return m;
    var result = <ClassElement, Set<InterfaceElement>>{};
    for (var interface in [
      ...library.classes,
      ...library.mixins,
      ...library.enums,
      ...library.extensionTypes,
    ]..sortBy((e) => e.name!)) {
      for (var superinterface in [
        interface.supertype,
        ...interface.interfaces,
        ...interface.mixins,
        if (interface is MixinElement) ...interface.superclassConstraints,
      ]) {
        if (superinterface == null) continue;
        var superinterfaceElement = superinterface.element;
        if (superinterfaceElement is ClassElement &&
            superinterfaceElement.isSealed) {
          (result[superinterfaceElement] ??= {}).add(interface);
        }
      }
    }
    _immediateSubinterfaceCache[library] = result;
    return result;
  }
}

/// Element categorization used by [MemberSortKey].
enum MemberCategory {
  constructor,
  propertyAccessor,
  topLevelFunctionOrMethod,
  interface,
  extension,
  typeAlias,
}

/// Sort key used to sort elements in the output.
class MemberSortKey implements Comparable<MemberSortKey> {
  final bool _isInstanceMember;
  final MemberCategory _category;
  final String _name;

  MemberSortKey(Element element)
    : _isInstanceMember = _computeIsInstanceMember(element),
      _category = _computeCategory(element),
      _name = element.name!;

  @override
  int compareTo(MemberSortKey other) {
    if ((_isInstanceMember ? 1 : 0).compareTo(other._isInstanceMember ? 1 : 0)
        case var value when value != 0) {
      return value;
    }
    if (_category.index.compareTo(other._category.index) case var value
        when value != 0) {
      return value;
    }
    return _name.compareTo(other._name);
  }

  static MemberCategory _computeCategory(Element element) => switch (element) {
    ConstructorElement() => MemberCategory.constructor,
    PropertyAccessorElement() => MemberCategory.propertyAccessor,
    TopLevelFunctionElement() => MemberCategory.topLevelFunctionOrMethod,
    MethodElement() => MemberCategory.topLevelFunctionOrMethod,
    InterfaceElement() => MemberCategory.interface,
    ExtensionElement() => MemberCategory.extension,
    TypeAliasElement() => MemberCategory.typeAlias,
    dynamic(:var runtimeType) =>
      throw UnimplementedError('Unexpected element: $runtimeType'),
  };

  static bool _computeIsInstanceMember(Element element) =>
      element.enclosingElement is InstanceElement &&
      switch (element) {
        ExecutableElement(:var isStatic) => !isStatic,
        dynamic(:var runtimeType) =>
          throw UnimplementedError('Unexpected element: $runtimeType'),
      };
}

/// A node to be printed to the output.
class Node<ChildSortKey extends Comparable<ChildSortKey>> {
  /// A list of objects which, when their string representations are
  /// concatenated, is the text that should be displayed on the first line of
  /// the node.
  ///
  /// The reason this is a list rather than a single string is to allow elements
  /// of the list to be [UniqueName] objects, which may acquire a disambiguation
  /// suffix at a later time.
  final text = <Object?>[];

  /// A list of child nodes, paired with a sort key indicating the order in
  /// which they should be output.
  final childNodes = <(ChildSortKey, Node)>[];

  /// Outputs [childNodes], prepending [prefix] to every line.
  void printChildren(StringSink sink, {required String prefix}) {
    _printNodes(sink, childNodes, prefix: prefix);
  }
}

/// Object that will have a unique string representation within the context of a
/// given [UniqueNamer] instance.
///
/// If two or more [UniqueName] objects are constructed with reference to the
/// same [UniqueNamer], and they have the same [_nameHint], then all such
/// objects' [toString] methods will append a unique suffix of the form
/// `@INTEGER`, so that the resulting strings are unique.
class UniqueName {
  /// The name that will be returned by [toString] if no disambiguation is
  /// needed.
  final String _nameHint;

  /// If not `Null`, the integer that [toString] will use to disambiguate this
  /// [UniqueName] from other ones with the same [_nameHint].
  int? _disambiguator;

  UniqueName(UniqueNamer uniqueNamer, this._nameHint) {
    // The uniqueness guarantee depends on `_nameHint` not containing an `@`.
    assert(!_nameHint.contains('@'));
    var conflicts = uniqueNamer._conflicts[_nameHint] ??= [];
    if (conflicts.length == 1) {
      conflicts[0]._disambiguator = 1;
    }
    conflicts.add(this);
    if (conflicts.length > 1) {
      _disambiguator = conflicts.length;
    }
  }

  @override
  String toString() =>
      [
        _nameHint,
        if (_disambiguator case var disambiguator?) '@$disambiguator',
      ].join();
}

/// Manager of unique names for elements.
class UniqueNamer {
  final _names = <Element, UniqueName>{};
  final _conflicts = <String, List<UniqueName>>{};

  /// Returns a [UniqueName] object whose [toString] method will produce a
  /// unique name for [element].
  UniqueName name(Element element) =>
      _names[element] ??= UniqueName(this, element.apiName);
}

/// URI categorization used by [UriSortKey].
enum UriCategory { inPackage, notInPackage }

/// Sort key used to sort libraries in the output.
///
/// Libraries in the specified package will be output first (sorted by URI),
/// followed by libraries not in the package.
class UriSortKey implements Comparable<UriSortKey> {
  final UriCategory _category;
  final String _uriString;

  UriSortKey(Uri uri, String pkgName)
    : _category =
          uri.isIn(pkgName) ? UriCategory.inPackage : UriCategory.notInPackage,
      _uriString = uri.toString();

  @override
  int compareTo(UriSortKey other) {
    if (_category.index.compareTo(other._category.index) case var value
        when value != 0) {
      return value;
    }
    return _uriString.compareTo(other._uriString);
  }
}

extension on Iterable<Iterable<Object?>> {
  /// Forms a list containing [prefix], followed by the elements of `this`
  /// (separated by [separator]), followed by [suffix].
  List<Object?> separate({
    String separator = ', ',
    String prefix = '',
    String suffix = '',
  }) {
    var result = <Object?>[prefix];
    var first = true;
    for (var item in this) {
      if (first) {
        first = false;
      } else {
        result.add(separator);
      }
      result.addAll(item);
    }
    result.add(suffix);
    return result;
  }
}

extension on Element {
  /// Returns the appropriate name for describing the element in `api.txt`.
  ///
  /// The name is the same as [name], but with `=` appended for setters.
  String get apiName {
    var apiName = name!;
    if (this is SetterElement) {
      apiName += '=';
    }
    return apiName;
  }

  bool isInPublicApiOf(String packageName) {
    if (this case PropertyAccessorElement(
      isSynthetic: true,
      :var variable,
    ) when variable.isInPublicApiOf(packageName)) {
      return true;
    }
    if (packageName == 'analyzer') {
      // Any element annotated with `@analyzerPublicApi` is considered to be
      // part of the public API of the analyzer package.
      if (metadata.annotations.any(_isPublicApiAnnotation)) {
        return true;
      }
    }
    if (name case var name? when !name.isPublic) return false;
    if (library!.uri.isInPublicLibOf(packageName)) return true;
    return false;
  }

  bool _isPublicApiAnnotation(ElementAnnotation annotation) {
    if (annotation.computeConstantValue() case DartObject(
      type: InterfaceType(element: InterfaceElement(name: 'AnalyzerPublicApi')),
    )) {
      return true;
    } else {
      return false;
    }
  }
}

extension on FormalParameterElement {
  bool get isDeprecated {
    // TODO(paulberry): add this to the analyzer public API
    return metadata.hasDeprecated;
  }
}

extension on String {
  bool get isPublic => !startsWith('_');
}

extension on Uri {
  bool isIn(String packageName) =>
      scheme == 'package' &&
      pathSegments.isNotEmpty &&
      pathSegments[0] == packageName;

  bool isInPublicLibOf(String packageName) =>
      scheme == 'package' &&
      pathSegments.length > 1 &&
      pathSegments[0] == packageName &&
      pathSegments[1] != 'src';
}
