// Copyright (c) 2020, 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 'dart:typed_data';

import 'package:_fe_analyzer_shared/src/scanner/token_impl.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/analysis/feature_set_provider.dart';
import 'package:analyzer/src/dart/analysis/unlinked_api_signature.dart';
import 'package:analyzer/src/dart/analysis/unlinked_data.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/micro/cider_byte_store.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/api_signature.dart';
import 'package:analyzer/src/summary/link.dart' as graph
    show DependencyWalker, Node;
import 'package:analyzer/src/summary2/data_reader.dart';
import 'package:analyzer/src/summary2/data_writer.dart';
import 'package:analyzer/src/summary2/informative_data.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:analyzer/src/workspace/workspace.dart';
import 'package:collection/collection.dart';
import 'package:convert/convert.dart';
import 'package:pub_semver/pub_semver.dart';

/// Ensure that the [FileState.libraryCycle] for the [file] and anything it
/// depends on is computed.
void computeLibraryCycle(Uint32List linkedSalt, FileState file) {
  var libraryWalker = _LibraryWalker(linkedSalt);
  libraryWalker.walk(libraryWalker.getNode(file));
}

class CiderUnlinkedUnit {
  /// Top-level declarations of the unit.
  final Set<String> topLevelDeclarations;

  /// Unlinked summary of the compilation unit.
  final UnlinkedUnit unit;

  CiderUnlinkedUnit({
    required this.topLevelDeclarations,
    required this.unit,
  });

  factory CiderUnlinkedUnit.fromBytes(Uint8List bytes) {
    return CiderUnlinkedUnit.read(
      SummaryDataReader(bytes),
    );
  }

  factory CiderUnlinkedUnit.read(SummaryDataReader reader) {
    return CiderUnlinkedUnit(
      topLevelDeclarations: reader.readStringUtf8Set(),
      unit: UnlinkedUnit.read(reader),
    );
  }

  Uint8List toBytes() {
    var byteSink = ByteSink();
    var sink = BufferedSink(byteSink);
    write(sink);
    return sink.flushAndTake();
  }

  void write(BufferedSink sink) {
    sink.writeStringUtf8Iterable(topLevelDeclarations);
    unit.write(sink);
  }
}

class FileState {
  final _FileStateUnlinked _unlinked;

  /// Files that reference this file.
  final List<FileState> referencingFiles = [];

  _FileStateFiles? _files;

  LibraryCycle? _libraryCycle;

  FileState._(this._unlinked);

  Uint8List get apiSignature => unlinkedUnit.apiSignature;

  Uint8List get digest => _unlinked.digest;

  bool get exists => _unlinked.exists;

  /// Return the [LibraryCycle] this file belongs to, even if it consists of
  /// just this file.  If the library cycle is not known yet, compute it.
  LibraryCycle get libraryCycle {
    if (_libraryCycle == null) {
      computeLibraryCycle(_fsState._linkedSalt, this);
    }
    return _libraryCycle!;
  }

  LineInfo get lineInfo => LineInfo(unlinkedUnit.lineStarts);

  FileState? get partOfLibrary => _unlinked.partOfLibrary;

  String get path => _location.path;

  /// The resolved signature of the file, that depends on the [libraryCycle]
  /// signature, and the content of the file.
  String get resolvedSignature {
    var signatureBuilder = ApiSignature();
    signatureBuilder.addString(path);
    signatureBuilder.addBytes(libraryCycle.signature);

    var content = getContent();
    signatureBuilder.addString(content);

    return signatureBuilder.toHex();
  }

  Source get source => _location.source;

  int get unlinkedId => _unlinked.unlinkedId;

  UnlinkedUnit get unlinkedUnit => _unlinked.unlinked.unit;

  Uri get uri => _location.uri;

  /// Return the [uri] string.
  String get uriStr => uri.toString();

  WorkspacePackage? get workspacePackage => _location.workspacePackage;

  FileSystemState get _fsState => _location._fsState;

  _FileStateLocation get _location => _unlinked.location;

  /// Collect all files that are transitively referenced by this file via
  /// imports, exports, and parts.
  void collectAllReferencedFiles(Set<String> referencedFiles) {
    for (var file in files().directReferencedFiles) {
      if (referencedFiles.add(file.path)) {
        file.collectAllReferencedFiles(referencedFiles);
      }
    }
  }

  _FileStateFiles files({
    OperationPerformanceImpl? performance,
  }) {
    return _files ??= _FileStateFiles(
      owner: this,
      performance: performance ?? OperationPerformanceImpl('<root>'),
    );
  }

  /// Return the content of the file, the empty string if cannot be read.
  ///
  /// We read the file digest, end verify that it is the same as the digest
  /// that was recorded during the file creation. If it is not, then the file
  /// was changed, and we failed to call [FileSystemState.changeFile].
  String getContent() {
    var contentWithDigest = _location._getContent();

    var digest = contentWithDigest.digest;
    if (!const ListEquality<int>().equals(digest, _unlinked.digest)) {
      throw StateError('File was changed, but not invalidated: $path');
    }

    return contentWithDigest.content;
  }

  void internal_setLibraryCycle(LibraryCycle cycle, String signature) {
    _libraryCycle = cycle;
  }

  CompilationUnitImpl parse(
      AnalysisErrorListener errorListener, String content) {
    return _FileStateUnlinked.parse(errorListener, _location, content);
  }

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

class FileSystemState {
  final ResourceProvider _resourceProvider;
  final CiderByteStore _byteStore;
  final SourceFactory _sourceFactory;
  final Workspace _workspace;
  final Uint32List _linkedSalt;

  /// A function that returns the digest for a file as a String. The function
  /// returns a non null value, returns an empty string if file does
  /// not exist/has no contents.
  final String Function(String path) getFileDigest;

  final Map<String, FileState> _pathToFile = {};
  final Map<Uri, FileState> _uriToFile = {};

  final FeatureSetProvider featureSetProvider;

  /// A function that fetches the given list of files. This function can be used
  /// to batch file reads in systems where file fetches are expensive.
  final void Function(List<String> paths)? prefetchFiles;

  /// A function that returns true if the given file path is likely to be that
  /// of a file that is generated.
  final bool Function(String path)? isGenerated;

  final FileSystemStateTimers timers2 = FileSystemStateTimers();

  final FileSystemStateTestView testView = FileSystemStateTestView();

  FileSystemState(
    this._resourceProvider,
    this._byteStore,
    this._sourceFactory,
    this._workspace,
    this._linkedSalt,
    this.featureSetProvider,
    this.getFileDigest,
    this.prefetchFiles,
    this.isGenerated,
  );

  /// Update the state to reflect the fact that the file with the given [path]
  /// was changed. Specifically this means that we evict this file and every
  /// file that referenced it.
  void changeFile(String path, List<FileState> removedFiles) {
    var file = _pathToFile.remove(path);
    if (file == null) {
      return;
    }

    removedFiles.add(file);
    _uriToFile.remove(file.uri);

    // The removed file does not reference other file anymore.
    for (var referencedFile in file.files().directReferencedFiles) {
      referencedFile.referencingFiles.remove(file);
    }

    // Recursively remove files that reference the removed file.
    for (var reference in file.referencingFiles.toList()) {
      changeFile(reference.path, removedFiles);
    }
  }

  /// Clears all the cached files. Returns the list of ids of all the removed
  /// files.
  Set<int> collectSharedDataIdentifiers() {
    var result = <int>{};
    for (var file in _pathToFile.values) {
      result.add(file._unlinked.unlinkedId);
    }
    return result;
  }

  FeatureSet contextFeatureSet(
    String path,
    Uri uri,
    WorkspacePackage? workspacePackage,
  ) {
    var workspacePackageExperiments = workspacePackage?.enabledExperiments;
    if (workspacePackageExperiments != null) {
      return featureSetProvider.featureSetForExperiments(
        workspacePackageExperiments,
      );
    }

    return featureSetProvider.getFeatureSet(path, uri);
  }

  Version contextLanguageVersion(
    String path,
    Uri uri,
    WorkspacePackage? workspacePackage,
  ) {
    var workspaceLanguageVersion = workspacePackage?.languageVersion;
    if (workspaceLanguageVersion != null) {
      return workspaceLanguageVersion;
    }

    return featureSetProvider.getLanguageVersion(path, uri);
  }

  FileState getFileForPath({
    required String path,
    required OperationPerformanceImpl performance,
  }) {
    var file = _pathToFile[path];
    if (file != null) {
      return file;
    }

    var uri = _sourceFactory.pathToUri(path);
    if (uri == null) {
      throw StateError('Unable to convert path to URI: $path');
    }

    var source = _sourceFactory.forUri2(uri);
    if (source == null) {
      throw StateError('Unable to resolve URI: $uri, path: $path');
    }

    return _newFile(
      source: source,
      performance: performance,
    );
  }

  FileState? getFileForUri({
    FileState? containingLibrary,
    required Uri uri,
    required OperationPerformanceImpl performance,
  }) {
    var file = _uriToFile[uri];
    if (file != null) {
      return file;
    }

    var source = _sourceFactory.forUri2(uri);
    if (source == null) {
      return null;
    }

    return _newFile(
      source: source,
      performance: performance,
    );
  }

  /// Returns a list of files whose contents contains the given string.
  /// Generated files are not included in the search.
  List<String> getFilesContaining(String value) {
    var result = <String>[];
    _pathToFile.forEach((path, file) {
      var genFile = isGenerated == null ? false : isGenerated!(path);
      if (!genFile && file.getContent().contains(value)) {
        result.add(path);
      }
    });
    return result;
  }

  /// Return files that have a top-level declaration with the [name].
  List<FileState> getFilesWithTopLevelDeclarations(String name) {
    var result = <FileState>[];
    for (var file in _pathToFile.values) {
      if (file._unlinked.unlinked.topLevelDeclarations.contains(name)) {
        result.add(file);
      }
    }
    return result;
  }

  String? getPathForUri(Uri uri) {
    return _sourceFactory.forUri2(uri)?.fullName;
  }

  /// Computes the set of [FileState]'s used/not used to analyze the given
  /// [files]. Removes the [FileState]'s of the files not used for analysis from
  /// the cache. Returns the set of unused [FileState]'s.
  List<FileState> removeUnusedFiles(List<String> files) {
    var allReferenced = <String>{};
    for (var path in files) {
      allReferenced.add(path);
      _pathToFile[path]?.collectAllReferencedFiles(allReferenced);
    }

    var unusedPaths = _pathToFile.keys.toSet();
    unusedPaths.removeAll(allReferenced);
    testView.removedPaths = unusedPaths;

    var removedFiles = <FileState>[];
    for (var path in unusedPaths) {
      var file = _pathToFile.remove(path)!;
      _uriToFile.remove(file.uri);
      removedFiles.add(file);
    }

    return removedFiles;
  }

  FileState _newFile({
    required Source source,
    required OperationPerformanceImpl performance,
  }) {
    var path = source.fullName;
    var uri = source.uri;

    var workspacePackage = _workspace.findPackageFor(path);
    var featureSet = contextFeatureSet(path, uri, workspacePackage);
    var packageLanguageVersion =
        contextLanguageVersion(path, uri, workspacePackage);

    var location = _FileStateLocation._(this, path, uri, source,
        workspacePackage, featureSet, packageLanguageVersion);
    var file = FileState._(
      _FileStateUnlinked(
        location: location,
        partOfLibrary: null,
        performance: performance,
      ),
    );
    _pathToFile[path] = file;
    _uriToFile[uri] = file;

    // Recurse with recording performance.
    file.files(performance: performance);

    return file;
  }
}

class FileSystemStateTestView {
  final List<String> refreshedFiles = [];
  final List<String> partsDiscoveredLibraries = [];
  Set<String> removedPaths = {};
}

class FileSystemStateTimer {
  final Stopwatch timer = Stopwatch();

  T run<T>(T Function() f) {
    timer.start();
    try {
      return f();
    } finally {
      timer.stop();
    }
  }

  Future<T> runAsync<T>(T Function() f) async {
    timer.start();
    try {
      return f();
    } finally {
      timer.stop();
    }
  }
}

class FileSystemStateTimers {
  final FileSystemStateTimer digest = FileSystemStateTimer();
  final FileSystemStateTimer read = FileSystemStateTimer();
  final FileSystemStateTimer parse = FileSystemStateTimer();
  final FileSystemStateTimer unlinked = FileSystemStateTimer();
  final FileSystemStateTimer prefetch = FileSystemStateTimer();

  void reset() {
    digest.timer.reset();
    read.timer.reset();
    parse.timer.reset();
    unlinked.timer.reset();
    prefetch.timer.reset();
  }
}

/// Information about libraries that reference each other, so form a cycle.
class LibraryCycle {
  /// The libraries that belong to this cycle.
  final List<FileState> libraries = [];

  /// The library cycles that this cycle references directly.
  final Set<LibraryCycle> directDependencies = <LibraryCycle>{};

  /// The transitive signature of this cycle.
  ///
  /// It is based on the API signatures of all files of the [libraries], and
  /// the signatures of the cycles that the [libraries] reference
  /// directly.  So, indirectly it is based on the transitive closure of all
  /// files that [libraries] reference (but we don't compute these files).
  late Uint8List signature;

  /// The hash of all the paths of the files in this cycle.
  late String cyclePathsHash;

  /// The ID of the resolution cache entry.
  /// It is `null` if we failed to load libraries of the cycle.
  int? resolutionId;

  LibraryCycle();

  String get signatureStr {
    return hex.encode(signature);
  }

  @override
  String toString() {
    return '[' + libraries.join(', ') + ']';
  }
}

class _ContentWithDigest {
  final String content;
  final Uint8List digest;

  _ContentWithDigest({
    required this.content,
    required this.digest,
  });
}

class _FileStateFiles {
  final List<FileState> imported = [];
  final List<FileState> exported = [];
  final List<FileState> parted = [];
  final List<FileState> ofLibrary = [];

  _FileStateFiles({
    required FileState owner,
    required OperationPerformanceImpl performance,
  }) {
    var unlinked = owner._unlinked;
    var location = unlinked.location;
    var unlinkedUnit = unlinked.unlinked.unit;

    // Build the graph.
    for (var directive in unlinkedUnit.imports) {
      var file = location._fileForRelativeUri(
        relativeUri: directive.uri,
        performance: performance,
      );
      if (file != null) {
        file.referencingFiles.add(owner);
        imported.add(file);
      }
    }
    for (var directive in unlinkedUnit.exports) {
      var file = location._fileForRelativeUri(
        relativeUri: directive.uri,
        performance: performance,
      );
      if (file != null) {
        exported.add(file);
        file.referencingFiles.add(owner);
      }
    }
    for (var uri in unlinkedUnit.parts) {
      var file = location._fileForRelativeUri(
        containingLibrary: owner,
        relativeUri: uri,
        performance: performance,
      );
      if (file != null) {
        parted.add(file);
        file.referencingFiles.add(owner);
      }
    }

    ofLibrary.add(owner);
    ofLibrary.addAll(parted);
  }

  /// Return all directly referenced files - imported, exported or parted.
  Set<FileState> get directReferencedFiles {
    return <FileState>{...imported, ...exported, ...parted};
  }

  /// Return all directly referenced libraries - imported or exported.
  Set<FileState> get directReferencedLibraries {
    return <FileState>{...imported, ...exported};
  }
}

class _FileStateLocation {
  final FileSystemState _fsState;

  /// The path of the file.
  final String path;

  /// The URI of the file.
  final Uri uri;

  /// The [Source] of the file with the [uri].
  final Source source;

  /// The [WorkspacePackage] that contains this file.
  ///
  /// It might be `null` if the file is outside of the workspace.
  final WorkspacePackage? workspacePackage;

  /// The [FeatureSet] for all files in the analysis context.
  ///
  /// Usually it is the feature set of the latest language version, plus
  /// possibly additional enabled experiments (from the analysis options file,
  /// or from SDK allowed experiments).
  ///
  /// This feature set is then restricted, with the [_packageLanguageVersion],
  /// or with a `@dart` language override token in the file header.
  final FeatureSet _contextFeatureSet;

  /// The language version for the package that contains this file.
  final Version _packageLanguageVersion;

  _FileStateLocation._(
    this._fsState,
    this.path,
    this.uri,
    this.source,
    this.workspacePackage,
    this._contextFeatureSet,
    this._packageLanguageVersion,
  );

  File get resource {
    return _fsState._resourceProvider.getFile(path);
  }

  Uri? resolveRelativeUriStr(String relativeUriStr) {
    if (relativeUriStr.isEmpty) {
      return null;
    }

    Uri relativeUri;
    try {
      relativeUri = Uri.parse(relativeUriStr);
    } on FormatException {
      return null;
    }

    return resolveRelativeUri(uri, relativeUri);
  }

  FileState? _fileForRelativeUri({
    FileState? containingLibrary,
    required String relativeUri,
    required OperationPerformanceImpl performance,
  }) {
    var absoluteUri = resolveRelativeUriStr(relativeUri);
    if (absoluteUri == null) {
      return null;
    }

    return _fsState.getFileForUri(
      containingLibrary: containingLibrary,
      uri: absoluteUri,
      performance: performance,
    );
  }

  /// This file has a `part of some.library;` directive. Because it does not
  /// specify the URI of the library, we don't know the library for sure.
  /// But usually the library is one of the sibling files.
  FileState? _findPartOfNameLibrary({
    required OperationPerformanceImpl performance,
  }) {
    var resourceProvider = _fsState._resourceProvider;
    var pathContext = resourceProvider.pathContext;

    var siblings = <Resource>[];
    try {
      siblings = resource.parent2.getChildren();
    } catch (_) {}

    for (var sibling in siblings) {
      if (file_paths.isDart(pathContext, sibling.path)) {
        var siblingState = _fsState.getFileForPath(
          path: sibling.path,
          performance: performance,
        );
        if (siblingState.files().parted.any((part) => part.path == path)) {
          return siblingState;
        }
      }
    }
    return null;
  }

  _ContentWithDigest _getContent() {
    String content;
    try {
      content = resource.readAsStringSync();
    } catch (_) {
      content = '';
    }

    var digestStr = _fsState.getFileDigest(path);
    var digest = utf8.encode(digestStr) as Uint8List;

    return _ContentWithDigest(content: content, digest: digest);
  }
}

class _FileStateUnlinked {
  final _FileStateLocation location;
  FileState? _partOfLibrary;

  final Uint8List digest;
  final bool exists;
  final CiderUnlinkedUnit unlinked;

  /// id of the cache entry with unlinked data.
  final int unlinkedId;

  factory _FileStateUnlinked({
    required _FileStateLocation location,
    required FileState? partOfLibrary,
    required OperationPerformanceImpl performance,
  }) {
    location._fsState.testView.refreshedFiles.add(location.path);

    int unlinkedId;
    CiderUnlinkedUnit unlinked;

    var digest = performance.run('digest', (performance) {
      performance.getDataInt('count').increment();
      var digestStr = location._fsState.getFileDigest(location.path);
      return utf8.encode(digestStr) as Uint8List;
    });

    var exists = digest.isNotEmpty;

    var unlinkedKey = '${location.path}.unlinked';
    var isUnlinkedFromCache = true;

    // Prepare bytes of the unlinked bundle - existing or new.
    // TODO(migration): should not be nullable
    Uint8List? unlinkedBytes;
    {
      var unlinkedData = location._fsState._byteStore.get(unlinkedKey, digest);
      unlinkedBytes = unlinkedData?.bytes;

      if (unlinkedBytes == null || unlinkedBytes.isEmpty) {
        isUnlinkedFromCache = false;

        var contentWithDigest = performance.run('content', (_) {
          return location._getContent();
        });
        digest = contentWithDigest.digest;
        var content = contentWithDigest.content;

        var unit = performance.run('parse', (performance) {
          performance.getDataInt('count').increment();
          performance.getDataInt('length').add(content.length);
          return parse(AnalysisErrorListener.NULL_LISTENER, location, content);
        });

        performance.run('unlinked', (performance) {
          var unlinkedUnit = serializeAstCiderUnlinked(unit);
          unlinkedBytes = unlinkedUnit.toBytes();
          performance.getDataInt('length').add(unlinkedBytes!.length);
          unlinkedData = location._fsState._byteStore
              .putGet(unlinkedKey, digest, unlinkedBytes!);
          unlinkedBytes = unlinkedData!.bytes;
        });

        unlinked = CiderUnlinkedUnit.fromBytes(unlinkedBytes!);
      }
      unlinkedId = unlinkedData!.id;
    }

    // Read the unlinked bundle.
    unlinked = CiderUnlinkedUnit.fromBytes(unlinkedBytes!);

    var result = _FileStateUnlinked._(
      location: location,
      partOfLibrary: partOfLibrary,
      digest: digest,
      exists: exists,
      unlinked: unlinked,
      unlinkedId: unlinkedId,
    );
    if (isUnlinkedFromCache) {
      performance.run('prefetch', (_) {
        result._prefetchDirectReferences();
      });
    }
    return result;
  }

  _FileStateUnlinked._({
    required this.location,
    required FileState? partOfLibrary,
    required this.digest,
    required this.exists,
    required this.unlinked,
    required this.unlinkedId,
  }) : _partOfLibrary = partOfLibrary;

  FileState? get partOfLibrary {
    var partOfLibrary = _partOfLibrary;
    if (partOfLibrary != null) {
      return partOfLibrary;
    }

    var performance = OperationPerformanceImpl('<root>');

    var libraryName = unlinked.unit.partOfName;
    if (libraryName != null) {
      location._fsState.testView.partsDiscoveredLibraries.add(location.path);
      return _partOfLibrary = location._findPartOfNameLibrary(
        performance: performance,
      );
    }

    var libraryUri = unlinked.unit.partOfUri;
    if (libraryUri == null) {
      return null;
    }
    location._fsState.testView.partsDiscoveredLibraries.add(location.path);
    return _partOfLibrary = location._fileForRelativeUri(
      relativeUri: libraryUri,
      performance: performance,
    );
  }

  void _prefetchDirectReferences() {
    var prefetchFiles = location._fsState.prefetchFiles;
    if (prefetchFiles == null) {
      return;
    }

    var paths = <String>{};

    void addRelativeUri(String relativeUri) {
      var absoluteUri = location.resolveRelativeUriStr(relativeUri);
      if (absoluteUri != null) {
        var path = location._fsState.getPathForUri(absoluteUri);
        if (path != null) {
          paths.add(path);
        }
      }
    }

    var unlinkedUnit = unlinked.unit;
    for (var directive in unlinkedUnit.imports) {
      addRelativeUri(directive.uri);
    }
    for (var directive in unlinkedUnit.exports) {
      addRelativeUri(directive.uri);
    }
    for (var uri in unlinkedUnit.parts) {
      addRelativeUri(uri);
    }

    prefetchFiles(paths.toList());
  }

  static CompilationUnitImpl parse(AnalysisErrorListener errorListener,
      _FileStateLocation location, String content) {
    CharSequenceReader reader = CharSequenceReader(content);
    Scanner scanner = Scanner(location.source, reader, errorListener)
      ..configureFeatures(
        featureSetForOverriding: location._contextFeatureSet,
        featureSet: location._contextFeatureSet.restrictToVersion(
          location._packageLanguageVersion,
        ),
      );
    Token token = scanner.tokenize(reportScannerErrors: false);
    LineInfo lineInfo = LineInfo(scanner.lineStarts);

    // Pass the feature set from the scanner to the parser
    // because the scanner may have detected a language version comment
    // and downgraded the feature set it holds.
    Parser parser = Parser(
      location.source,
      errorListener,
      featureSet: scanner.featureSet,
      lineInfo: lineInfo,
    );
    parser.enableOptionalNewAndConst = true;
    var unit = parser.parseCompilationUnit(token);

    // StringToken uses a static instance of StringCanonicalizer, so we need
    // to clear it explicitly once we are done using it for this file.
    StringToken.canonicalizer.clear();

    // TODO(scheglov) Use actual versions.
    unit.languageVersion = LibraryLanguageVersion(
      package: ExperimentStatus.currentVersion,
      override: null,
    );

    return unit;
  }

  static CiderUnlinkedUnit serializeAstCiderUnlinked(CompilationUnit unit) {
    var exports = <UnlinkedNamespaceDirective>[];
    var imports = <UnlinkedNamespaceDirective>[];
    var parts = <String>[];
    var hasDartCoreImport = false;
    var hasLibraryDirective = false;
    var hasPartOfDirective = false;
    String? partOfName;
    String? partOfUriStr;
    for (var directive in unit.directives) {
      if (directive is ExportDirective) {
        var builder = _serializeNamespaceDirective(directive);
        exports.add(builder);
      } else if (directive is ImportDirective) {
        var builder = _serializeNamespaceDirective(directive);
        imports.add(builder);
        if (builder.uri == 'dart:core') {
          hasDartCoreImport = true;
        }
      } else if (directive is LibraryDirective) {
        hasLibraryDirective = true;
      } else if (directive is PartDirective) {
        var uriStr = directive.uri.stringValue;
        parts.add(uriStr ?? '');
      } else if (directive is PartOfDirective) {
        hasPartOfDirective = true;
        var libraryName = directive.libraryName;
        var uriStr = directive.uri?.stringValue;
        if (libraryName != null) {
          partOfName = libraryName.components.map((e) => e.name).join('.');
        } else if (uriStr != null) {
          partOfUriStr = uriStr;
        }
      }
    }
    if (!hasDartCoreImport) {
      imports.add(
        UnlinkedNamespaceDirective(
          configurations: [],
          uri: 'dart:core',
        ),
      );
    }

    var topLevelDeclarations = <String>{};
    for (var declaration in unit.declarations) {
      if (declaration is ClassDeclaration) {
        topLevelDeclarations.add(declaration.name.name);
      } else if (declaration is EnumDeclaration) {
        topLevelDeclarations.add(declaration.name.name);
      } else if (declaration is ExtensionDeclaration) {
        var name = declaration.name;
        if (name != null) {
          topLevelDeclarations.add(name.name);
        }
      } else if (declaration is FunctionDeclaration) {
        topLevelDeclarations.add(declaration.name.name);
      } else if (declaration is MixinDeclaration) {
        topLevelDeclarations.add(declaration.name.name);
      } else if (declaration is TopLevelVariableDeclaration) {
        for (var variable in declaration.variables.variables) {
          topLevelDeclarations.add(variable.name.name);
        }
      }
    }

    var unlinkedUnit = UnlinkedUnit(
      apiSignature: computeUnlinkedApiSignature(unit),
      exports: exports,
      hasLibraryDirective: hasLibraryDirective,
      hasPartOfDirective: hasPartOfDirective,
      imports: imports,
      informativeBytes: writeUnitInformative(unit),
      lineStarts: Uint32List.fromList(unit.lineInfo.lineStarts),
      partOfName: partOfName,
      partOfUri: partOfUriStr,
      parts: parts,
    );

    return CiderUnlinkedUnit(
      unit: unlinkedUnit,
      topLevelDeclarations: topLevelDeclarations,
    );
  }

  static UnlinkedNamespaceDirective _serializeNamespaceDirective(
    NamespaceDirective directive,
  ) {
    return UnlinkedNamespaceDirective(
      configurations: directive.configurations.map((configuration) {
        var name = configuration.name.components.join('.');
        var value = configuration.value?.stringValue ?? '';
        return UnlinkedNamespaceDirectiveConfiguration(
          name: name,
          value: value,
          uri: configuration.uri.stringValue ?? '',
        );
      }).toList(),
      uri: directive.uri.stringValue ?? '',
    );
  }
}

/// Node in [_LibraryWalker].
class _LibraryNode extends graph.Node<_LibraryNode> {
  final _LibraryWalker walker;
  final FileState file;

  _LibraryNode(this.walker, this.file);

  @override
  bool get isEvaluated => file._libraryCycle != null;

  @override
  List<_LibraryNode> computeDependencies() {
    return file.files().directReferencedLibraries.map(walker.getNode).toList();
  }
}

/// Helper that organizes dependencies of a library into topologically
/// sorted [LibraryCycle]s.
class _LibraryWalker extends graph.DependencyWalker<_LibraryNode> {
  final Uint32List _linkedSalt;
  final Map<FileState, _LibraryNode> nodesOfFiles = {};

  _LibraryWalker(this._linkedSalt);

  @override
  void evaluate(_LibraryNode v) {
    evaluateScc([v]);
  }

  @override
  void evaluateScc(List<_LibraryNode> scc) {
    var cycle = LibraryCycle();

    var signature = ApiSignature();
    signature.addUint32List(_linkedSalt);

    // Sort libraries to produce stable signatures.
    scc.sort((first, second) {
      var firstPath = first.file.path;
      var secondPath = second.file.path;
      return firstPath.compareTo(secondPath);
    });

    // Append direct referenced cycles.
    for (var node in scc) {
      var file = node.file;
      _appendDirectlyReferenced(cycle, signature, file.files().imported);
      _appendDirectlyReferenced(cycle, signature, file.files().exported);
    }

    // Fill the cycle with libraries.
    for (var node in scc) {
      cycle.libraries.add(node.file);

      signature.addString(node.file.uriStr);

      signature.addInt(node.file.files().ofLibrary.length);
      for (var file in node.file.files().ofLibrary) {
        signature.addBool(file.exists);
        signature.addBytes(file.apiSignature);
      }
    }

    // Compute the general library cycle signature.
    cycle.signature = signature.toByteList();

    // Compute the cycle file paths signature.
    var filePathsSignature = ApiSignature();
    for (var node in scc) {
      filePathsSignature.addString(node.file.path);
    }
    cycle.cyclePathsHash = filePathsSignature.toHex();

    // Compute library specific signatures.
    for (var node in scc) {
      var librarySignatureBuilder = ApiSignature()
        ..addString(node.file.uriStr)
        ..addBytes(cycle.signature);
      var librarySignature = librarySignatureBuilder.toHex();

      node.file.internal_setLibraryCycle(
        cycle,
        librarySignature,
      );
    }
  }

  _LibraryNode getNode(FileState file) {
    return nodesOfFiles.putIfAbsent(file, () => _LibraryNode(this, file));
  }

  void _appendDirectlyReferenced(
    LibraryCycle cycle,
    ApiSignature signature,
    List<FileState> directlyReferenced,
  ) {
    signature.addInt(directlyReferenced.length);
    for (var referencedLibrary in directlyReferenced) {
      var referencedCycle = referencedLibrary._libraryCycle;
      // We get null when the library is a part of the cycle being build.
      if (referencedCycle == null) continue;

      if (cycle.directDependencies.add(referencedCycle)) {
        signature.addBytes(referencedCycle.signature);
      }
    }
  }
}
