// 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:collection';
import 'dart:typed_data';

import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/dart/element/element.dart'
    show CompilationUnitElement, LibraryElement;
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/analysis/analysis_options_map.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/analysis/info_declaration_store.dart';
import 'package:analyzer/src/dart/analysis/library_graph.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/analysis/session.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/exception/exception.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/summary2/bundle_reader.dart';
import 'package:analyzer/src/summary2/link.dart';
import 'package:analyzer/src/summary2/linked_element_factory.dart';
import 'package:analyzer/src/summary2/macro.dart';
import 'package:analyzer/src/summary2/macro_cache.dart';
import 'package:analyzer/src/summary2/reference.dart';
import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:collection/collection.dart';
import 'package:path/path.dart';

/// Context information necessary to analyze one or more libraries within an
/// [AnalysisDriver].
///
/// Currently this is implemented as a wrapper around [AnalysisContext].
class LibraryContext {
  final LibraryContextTestData? testData;
  final PerformanceLog logger;
  final ByteStore byteStore;
  final InfoDeclarationStore infoDeclarationStore;
  final FileSystemState fileSystemState;
  final MacroSupport? macroSupport;
  final File? packagesFile;
  final SummaryDataStore store = SummaryDataStore();

  late final AnalysisContextImpl analysisContext;
  late final LinkedElementFactory elementFactory;

  Set<LibraryCycle> loadedBundles = Set.identity();

  LibraryContext({
    required this.testData,
    required AnalysisSessionImpl analysisSession,
    required this.logger,
    required this.byteStore,
    required this.infoDeclarationStore,
    required this.fileSystemState,
    required AnalysisOptionsMap analysisOptionsMap,
    required DeclaredVariables declaredVariables,
    required SourceFactory sourceFactory,
    required this.macroSupport,
    required this.packagesFile,
    required SummaryDataStore? externalSummaries,
  }) {
    analysisContext = AnalysisContextImpl(
      analysisOptionsMap: analysisOptionsMap,
      declaredVariables: declaredVariables,
      sourceFactory: sourceFactory,
    );

    elementFactory = LinkedElementFactory(
      analysisContext,
      analysisSession,
      Reference.root(),
      macroSupport,
    );
    if (externalSummaries != null) {
      for (var bundle in externalSummaries.bundles) {
        elementFactory.addBundle(
          BundleReader(
            elementFactory: elementFactory,
            resolutionBytes: bundle.resolutionBytes,
            unitsInformativeBytes: {},
            infoDeclarationStore: infoDeclarationStore,
          ),
        );
      }
    }
  }

  /// Computes a [CompilationUnitElement] for the given library/unit pair.
  CompilationUnitElementImpl computeUnitElement(
    LibraryFileKind library,
    FileState unit,
  ) {
    var reference = elementFactory.rootReference
        .getChild(library.file.uriStr)
        .getChild('@fragment')
        .getChild(unit.uriStr);
    var element = elementFactory.elementOfReference(reference);
    return element as CompilationUnitElementImpl;
  }

  /// Notifies this object that it is about to be discarded.
  ///
  /// Returns the keys of the artifacts that are no longer used.
  Set<String> dispose() {
    var keys = unloadAll();
    elementFactory.dispose();
    return keys;
  }

  /// Get the [LibraryElement] for the given library.
  LibraryElement getLibraryElement(Uri uri) {
    _createElementFactoryTypeProvider();
    return elementFactory.libraryOfUri2(uri);
  }

  /// Load data required to access elements of the given [targetLibrary].
  Future<void> load({
    required LibraryFileKind targetLibrary,
    required OperationPerformanceImpl performance,
  }) async {
    addToLogRing('[load][targetLibrary: ${targetLibrary.file}]');
    var librariesTotal = 0;
    var librariesLoaded = 0;
    var librariesLinked = 0;
    var librariesLinkedTimer = Stopwatch();
    var bytesGet = 0;
    var bytesPut = 0;

    Future<void> loadBundle(LibraryCycle cycle) async {
      if (!loadedBundles.add(cycle)) return;

      performance.getDataInt('cycleCount').increment();
      performance.getDataInt('libraryCount').add(cycle.libraries.length);

      librariesTotal += cycle.libraries.length;

      for (var directDependency in cycle.directDependencies) {
        await loadBundle(directDependency);
      }

      var unitsInformativeBytes = <Uri, Uint8List>{};
      var macroLibraries = <MacroLibrary>[];
      for (var library in cycle.libraries) {
        var macroClasses = <MacroClass>[];
        for (var file in library.files) {
          unitsInformativeBytes[file.uri] = file.unlinked2.informativeBytes;
          for (var macroClass in file.unlinked2.macroClasses) {
            macroClasses.add(
              MacroClass(
                name: macroClass.name,
                constructors: macroClass.constructors,
              ),
            );
          }
        }
        if (macroClasses.isNotEmpty) {
          macroLibraries.add(
            MacroLibrary(
              uri: library.file.uri,
              path: library.file.path,
              classes: macroClasses,
            ),
          );
        }
      }

      var macroResultKey = cycle.cachedMacrosKey;
      var inputMacroResults = <LibraryFileKind, MacroResultInput>{};
      if (byteStore.get(macroResultKey) case var bytes?) {
        _readMacroResults(
          cycle: cycle,
          bytes: bytes,
          macroResults: inputMacroResults,
        );
      }

      var linkedBytes = byteStore.get(cycle.linkedKey);

      if (linkedBytes == null) {
        librariesLinkedTimer.start();

        testData?.linkedCycles.add(
          cycle.libraries.map((e) => e.file.path).toSet(),
        );

        LinkResult linkResult;
        try {
          linkResult = await performance.runAsync(
            'link',
            (performance) async {
              return await link(
                elementFactory: elementFactory,
                performance: performance,
                inputLibraries: cycle.libraries,
                inputMacroResults: inputMacroResults,
                macroExecutor: this.macroSupport?.executor,
              );
            },
          );
          librariesLinked += cycle.libraries.length;
        } catch (exception, stackTrace) {
          _throwLibraryCycleLinkException(cycle, exception, stackTrace);
        }

        linkedBytes = linkResult.resolutionBytes;
        byteStore.putGet(cycle.linkedKey, linkedBytes);
        performance.getDataInt('bytesPut').add(linkedBytes.length);
        testData?.forCycle(cycle).putKeys.add(cycle.linkedKey);
        bytesPut += linkedBytes.length;

        _writeMacroResults(
          cycle: cycle,
          linkResult: linkResult,
          macroResultKey: macroResultKey,
        );

        librariesLinkedTimer.stop();
      } else {
        testData?.forCycle(cycle).getKeys.add(cycle.linkedKey);
        performance.getDataInt('bytesGet').add(linkedBytes.length);
        performance.getDataInt('libraryLoadCount').add(cycle.libraries.length);
        // TODO(scheglov): Take / clear parsed units in files.
        bytesGet += linkedBytes.length;
        librariesLoaded += cycle.libraries.length;
        var bundleReader = BundleReader(
          elementFactory: elementFactory,
          unitsInformativeBytes: unitsInformativeBytes,
          resolutionBytes: linkedBytes,
          infoDeclarationStore: infoDeclarationStore,
        );
        elementFactory.addBundle(bundleReader);
        _addMacroParts(cycle, bundleReader);
      }

      // If we can compile to kernel, check if there are macros.
      var macroSupport = this.macroSupport;
      var packagesFile = this.packagesFile;
      if (macroSupport is KernelMacroSupport &&
          packagesFile != null &&
          macroLibraries.isNotEmpty) {
        var kernelBytes = byteStore.get(cycle.macroKey);
        if (kernelBytes == null) {
          kernelBytes = await performance.runAsync<Uint8List>(
            'macroCompileKernel',
            (performance) async {
              return await macroSupport.builder.build(
                fileSystem: _MacroFileSystem(fileSystemState),
                packageFilePath: packagesFile.path,
                libraries: macroLibraries,
              );
            },
          );
          byteStore.putGet(cycle.macroKey, kernelBytes);
          bytesPut += kernelBytes.length;
        } else {
          bytesGet += kernelBytes.length;
        }

        elementFactory.addKernelMacroBundle(
          macroSupport: macroSupport,
          kernelBytes: kernelBytes,
          libraries: cycle.libraries.map((e) => e.file.uri).toSet(),
        );
      }
    }

    await logger.runAsync('Prepare linked bundles', () async {
      var libraryCycle = performance.run('libraryCycle', (performance) {
        fileSystemState.newFileOperationPerformance = performance;
        try {
          return targetLibrary.libraryCycle;
        } finally {
          fileSystemState.newFileOperationPerformance = null;
        }
      });
      await loadBundle(libraryCycle);
      logger.writeln(
        '[librariesTotal: $librariesTotal]'
        '[librariesLoaded: $librariesLoaded]'
        '[librariesLinked: $librariesLinked]'
        '[librariesLinkedTimer: ${librariesLinkedTimer.elapsedMilliseconds} ms]'
        '[bytesGet: $bytesGet][bytesPut: $bytesPut]',
      );
    });

    // There might be a rare (and wrong) situation, when the external summaries
    // already include the [targetLibrary]. When this happens, [loadBundle]
    // exists without doing any work. But the type provider must be created.
    _createElementFactoryTypeProvider();
  }

  /// Remove libraries represented by the [removed] files.
  /// If we need these libraries later, we will relink and reattach them.
  void remove(Set<FileState> removed, Set<String> removedKeys) {
    elementFactory.removeLibraries(
      removed.map((e) => e.uri).toSet(),
    );

    loadedBundles.removeWhere((cycle) {
      var cycleFiles = cycle.libraries.map((e) => e.file);
      if (cycleFiles.any(removed.contains)) {
        removedKeys.add(cycle.linkedKey);
        return true;
      }
      return false;
    });
  }

  /// Unloads all loaded bundles.
  ///
  /// Returns the keys of the artifacts that are no longer used.
  Set<String> unloadAll() {
    var keySet = <String>{};
    var uriSet = <Uri>{};

    for (var cycle in loadedBundles) {
      keySet.add(cycle.linkedKey);
      uriSet.addAll(cycle.libraries.map((e) => e.file.uri));
    }

    elementFactory.removeLibraries(uriSet);
    loadedBundles.clear();

    return keySet;
  }

  /// Create files with macro generated parts.
  void _addMacroParts(LibraryCycle cycle, BundleReader bundleReader) {
    for (var libraryReader in bundleReader.libraryMap.values) {
      var macroGeneratedCode = libraryReader.macroGeneratedCode;
      if (macroGeneratedCode != null) {
        for (var libraryKind in cycle.libraries) {
          if (libraryKind.file.uri == libraryReader.uri) {
            libraryKind.addMacroPart(
              macroGeneratedCode,
              partialIndex: null,
              performance: OperationPerformanceImpl('<root>'),
            );
          }
        }
      }
    }
  }

  /// Ensure that type provider is created.
  void _createElementFactoryTypeProvider() {
    if (!analysisContext.hasTypeProvider) {
      elementFactory.createTypeProviders(
        elementFactory.dartCoreElement,
        elementFactory.dartAsyncElement,
      );
    }
  }

  /// Fills [macroResults] with results that can be reused.
  void _readMacroResults({
    required LibraryCycle cycle,
    required Uint8List bytes,
    required Map<LibraryFileKind, MacroResultInput> macroResults,
  }) {
    var bundle = MacroCacheBundle.fromBytes(cycle, bytes);
    var testUsedList = <File>[];
    for (var library in bundle.libraries) {
      // If the library itself changed, then declarations that macros see
      // could be different now.
      if (!ListEquality<int>().equals(
        library.apiSignature,
        library.kind.apiSignature,
      )) {
        continue;
      }

      // TODO(scheglov): Record more specific dependencies.
      if (library.hasAnyIntrospection) {
        continue;
      }

      testUsedList.add(library.kind.file.resource);

      macroResults[library.kind] = MacroResultInput(
        code: library.code,
      );
    }

    if (testUsedList.isNotEmpty) {
      var cycleTestData = testData?.forCycle(cycle);
      cycleTestData?.macrosUsedCached.add(testUsedList);
    }
  }

  /// The [exception] was caught during the [cycle] linking.
  ///
  /// Throw another exception that wraps the given one, with more information.
  Never _throwLibraryCycleLinkException(
    LibraryCycle cycle,
    Object exception,
    StackTrace stackTrace,
  ) {
    var fileContentMap = <String, String>{};
    for (var library in cycle.libraries) {
      for (var file in library.files) {
        fileContentMap[file.path] = file.content;
      }
    }
    throw CaughtExceptionWithFiles(exception, stackTrace, fileContentMap);
  }

  void _writeMacroResults({
    required LibraryCycle cycle,
    required LinkResult linkResult,
    required String macroResultKey,
  }) {
    var results = linkResult.macroResults;
    if (results.isEmpty) {
      return;
    }

    testData?.forCycle(cycle).macrosGenerated.add(
          linkResult.macroResults
              .map((result) => result.library.file.resource)
              .toList(),
        );

    var bundle = MacroCacheBundle(
      libraries: results.map((result) {
        return MacroCacheLibrary(
          kind: result.library,
          apiSignature: result.library.apiSignature,
          hasAnyIntrospection: result.processing.hasAnyIntrospection,
          code: result.code,
        );
      }).toList(),
    );

    var bytes = bundle.toBytes();
    byteStore.putGet(macroResultKey, bytes);
  }
}

class LibraryContextTestData {
  final FileSystemTestData fileSystemTestData;

  // TODO(scheglov): Use [libraryCycles] and textual dumps for the driver too.
  final List<Set<String>> linkedCycles = [];

  /// Keys: the sorted list of library files.
  final Map<List<FileTestData>, LibraryCycleTestData> libraryCycles =
      LinkedHashMap(
    hashCode: Object.hashAll,
    equals: const ListEquality<FileTestData>().equals,
  );

  LibraryContextTestData({
    required this.fileSystemTestData,
  });

  LibraryCycleTestData forCycle(LibraryCycle cycle) {
    var files = cycle.libraries.map((library) {
      var file = library.file;
      return fileSystemTestData.forFile(file.resource, file.uri);
    }).toList();
    files.sortBy((fileData) => fileData.file.path);

    return libraryCycles[files] ??= LibraryCycleTestData();
  }
}

class LibraryCycleTestData {
  final List<String> getKeys = [];
  final List<String> putKeys = [];
  final List<List<File>> macrosUsedCached = [];
  final List<List<File>> macrosGenerated = [];
}

class _MacroFileEntry implements MacroFileEntry {
  @override
  final String content;

  @override
  final bool exists;

  _MacroFileEntry({
    required this.content,
    required this.exists,
  });
}

class _MacroFileSystem implements MacroFileSystem {
  final FileSystemState fileSystemState;

  _MacroFileSystem(this.fileSystemState);

  @override
  Context get pathContext => fileSystemState.pathContext;

  @override
  MacroFileEntry getFile(String path) {
    var fileState = fileSystemState.getExistingFromPath(path);
    if (fileState != null) {
      return _MacroFileEntry(
        content: fileState.content,
        exists: fileState.exists,
      );
    }

    var fileContent = fileSystemState.fileContentStrategy.get(path);
    return _MacroFileEntry(
      content: fileContent.content,
      exists: fileContent.exists,
    );
  }
}
