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

import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/context/packages.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver.dart' show ErrorEncoding;
import 'package:analyzer/src/dart/analysis/feature_set_provider.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/analysis/results.dart';
import 'package:analyzer/src/dart/analysis/session.dart';
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
import 'package:analyzer/src/dart/micro/analysis_context.dart';
import 'package:analyzer/src/dart/micro/library_analyzer.dart';
import 'package:analyzer/src/dart/micro/library_graph.dart';
import 'package:analyzer/src/generated/engine.dart'
    show AnalysisEngine, AnalysisOptionsImpl;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/api_signature.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/link.dart' as link2;
import 'package:analyzer/src/summary2/linked_bundle_context.dart';
import 'package:analyzer/src/summary2/linked_element_factory.dart';
import 'package:analyzer/src/summary2/reference.dart';
import 'package:analyzer/src/task/options.dart';
import 'package:analyzer/src/workspace/workspace.dart';
import 'package:collection/collection.dart';
import 'package:meta/meta.dart';
import 'package:yaml/yaml.dart';

class FileResolver {
  final PerformanceLog logger;
  final ResourceProvider resourceProvider;
  final MemoryByteStore byteStore;
  final SourceFactory sourceFactory;

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

  /**
   * 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;

  final Workspace workspace;

  /// This field gets value only during testing.
  FileResolverTestView testView;

  MicroAnalysisContextImpl analysisContext;

  FileSystemState fsState;

  _LibraryContext libraryContext;

  FileResolver(this.logger, this.resourceProvider, this.byteStore,
      this.sourceFactory, this.getFileDigest, this.prefetchFiles,
      {@required Workspace workspace})
      : this.workspace = workspace;

  FeatureSet get defaultFeatureSet => FeatureSet.fromEnableFlags([]);

  ErrorsResult getErrors(String path) {
    _throwIfNotAbsoluteNormalizedPath(path);

    return logger.run('Get errors for $path', () {
      var fileContext = _createFileContext(path);
      var file = fileContext.file;

      var errorsSignatureBuilder = ApiSignature();
      errorsSignatureBuilder.addBytes(file.libraryCycle.signature);
      errorsSignatureBuilder.addBytes(file.digest);
      var errorsSignature = errorsSignatureBuilder.toByteList();

      var errorsKey = file.path + '.errors';
      var bytes = byteStore.get(errorsKey);

      List<AnalysisError> errors;
      if (bytes != null) {
        var data = CiderUnitErrors.fromBuffer(bytes);
        if (const ListEquality().equals(data.signature, errorsSignature)) {
          errors = data.errors.map((error) {
            return ErrorEncoding.decode(file.source, error);
          }).toList();
        }
      }

      if (errors == null) {
        var unitResult = resolve(path);
        errors = unitResult.errors;

        bytes = CiderUnitErrorsBuilder(
          signature: errorsSignature,
          errors: errors.map((ErrorEncoding.encode)).toList(),
        ).toBuffer();
        byteStore.put(errorsKey, bytes);
      }

      return ErrorsResultImpl(
        libraryContext.analysisSession,
        path,
        file.uri,
        file.lineInfo,
        false, // isPart
        errors,
      );
    });
  }

  ResolvedUnitResult resolve(String path) {
    _throwIfNotAbsoluteNormalizedPath(path);

    return logger.run('Resolve $path', () {
      var fileContext = _createFileContext(path);
      var file = fileContext.file;

      libraryContext.load2(file);

      testView?.addResolvedFile(path);

      var errorListener = RecordingErrorListener();
      var content = resourceProvider.getFile(path).readAsStringSync();
      var unit = file.parse(errorListener, content);

      Map<FileState, UnitAnalysisResult> results;
      logger.run('Compute analysis results', () {
        var libraryAnalyzer = LibraryAnalyzer(
          fileContext.analysisOptions,
          analysisContext.declaredVariables,
          sourceFactory,
          (_) => true,
          // _isLibraryUri
          libraryContext.analysisContext,
          libraryContext.elementFactory,
          libraryContext.inheritanceManager,
          file,
          resourceProvider,
          (String path) => resourceProvider.getFile(path).readAsStringSync(),
        );

        results = libraryAnalyzer.analyzeSync();
      });
      UnitAnalysisResult fileResult = results[file];

      return ResolvedUnitResultImpl(
        analysisContext.currentSession,
        path,
        file.uri,
        file.exists,
        content,
        unit.lineInfo,
        false, // isPart
        fileResult.unit,
        fileResult.errors,
      );
    });
  }

  /// Make sure that [analysisContext], [fsState] and [libraryContext] are
  /// compatible with the given [fileAnalysisOptions].
  ///
  /// Specifically we check that `implicit-casts` and `strict-inference`
  /// flags are the same, so the type systems would be the same.
  void _createContext(AnalysisOptionsImpl fileAnalysisOptions) {
    if (analysisContext != null) {
      var analysisOptions = analysisContext.analysisOptions;
      var analysisOptionsImpl = analysisOptions as AnalysisOptionsImpl;
      if (analysisOptionsImpl.implicitCasts !=
              fileAnalysisOptions.implicitCasts ||
          analysisOptionsImpl.strictInference !=
              fileAnalysisOptions.strictInference) {
        logger.writeln(
          'Reset the context, different type system affecting options.',
        );
        fsState = null; // TODO(scheglov) don't do this
        analysisContext = null;
        libraryContext = null;
      }
    }

    var analysisOptions = AnalysisOptionsImpl()
      ..implicitCasts = fileAnalysisOptions.implicitCasts
      ..strictInference = fileAnalysisOptions.strictInference;

    if (fsState == null) {
      var featureSetProvider = FeatureSetProvider.build(
        resourceProvider: resourceProvider,
        packages: Packages.empty,
        packageDefaultFeatureSet: analysisOptions.contextFeatures,
        nonPackageDefaultFeatureSet: analysisOptions.nonPackageFeatureSet,
      );

      fsState = FileSystemState(
        logger,
        resourceProvider,
        byteStore,
        sourceFactory,
        analysisOptions,
        Uint32List(0), // linkedSalt
        featureSetProvider,
        getFileDigest,
        prefetchFiles,
      );
    }

    if (analysisContext == null) {
      logger.run('Create AnalysisContext', () {
        var root = ContextRootImpl(
          resourceProvider,
          resourceProvider.getFolder(workspace.root),
        );

        analysisContext = MicroAnalysisContextImpl(
          this,
          root,
          analysisOptions,
          DeclaredVariables(),
          sourceFactory,
          resourceProvider,
          workspace: workspace,
        );
      });
    }

    if (libraryContext == null) {
      libraryContext = _LibraryContext(
        logger,
        resourceProvider,
        byteStore,
        analysisContext.currentSession,
        analysisContext.analysisOptions,
        sourceFactory,
        analysisContext.declaredVariables,
      );
    }
  }

  _FileContext _createFileContext(String path) {
    var analysisOptions = _getAnalysisOptions(path);

    _createContext(analysisOptions);

    var file = logger.run('Get file $path', () {
      return fsState.getFileForPath(path);
    });

    return _FileContext(analysisOptions, file);
  }

  File _findOptionsFile(Folder folder) {
    while (folder != null) {
      File packagesFile =
          _getFile(folder, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
      if (packagesFile != null) {
        return packagesFile;
      }
      folder = folder.parent;
    }
    return null;
  }

  /// Return the analysis options.
  ///
  /// If the [optionsFile] is not `null`, read it.
  ///
  /// If the [workspace] is a [WorkspaceWithDefaultAnalysisOptions], get the
  /// default options, if the file exists.
  ///
  /// Otherwise, return the default options.
  AnalysisOptionsImpl _getAnalysisOptions(String path) {
    YamlMap optionMap;
    var folder = resourceProvider.getFile(path).parent;
    var optionsFile = _findOptionsFile(folder);
    if (optionsFile != null) {
      try {
        var optionsProvider = AnalysisOptionsProvider(sourceFactory);
        optionMap = optionsProvider.getOptionsFromFile(optionsFile);
      } catch (e) {
        // ignored
      }
    } else {
      Source source;
      if (workspace is WorkspaceWithDefaultAnalysisOptions) {
        source = sourceFactory.forUri(WorkspaceWithDefaultAnalysisOptions.uri);
      }

      if (source != null && source.exists()) {
        try {
          var optionsProvider = AnalysisOptionsProvider(sourceFactory);
          optionMap = optionsProvider.getOptionsFromSource(source);
        } catch (e) {
          // ignored
        }
      }
    }

    var options = AnalysisOptionsImpl();

    if (optionMap != null) {
      applyToAnalysisOptions(options, optionMap);
    }

    return options;
  }

  void _throwIfNotAbsoluteNormalizedPath(String path) {
    var pathContext = resourceProvider.pathContext;
    if (pathContext.normalize(path) != path) {
      throw ArgumentError(
        'Only normalized paths are supported: $path',
      );
    }
  }

  static File _getFile(Folder directory, String name) {
    Resource resource = directory.getChild(name);
    if (resource is File && resource.exists) {
      return resource;
    }
    return null;
  }
}

class FileResolverTestView {
  /// The paths of files which were resolved.
  ///
  /// The file path is added every time when it is resolved.
  final List<String> resolvedFiles = [];

  void addResolvedFile(String path) {
    resolvedFiles.add(path);
  }
}

class _FileContext {
  final AnalysisOptionsImpl analysisOptions;
  final FileState file;

  _FileContext(this.analysisOptions, this.file);
}

class _LibraryContext {
  final PerformanceLog logger;
  final ResourceProvider resourceProvider;
  final MemoryByteStore byteStore;
  final AnalysisSession analysisSession;

  AnalysisContextImpl analysisContext;
  LinkedElementFactory elementFactory;
  InheritanceManager3 inheritanceManager;

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

  _LibraryContext(
    this.logger,
    this.resourceProvider,
    this.byteStore,
    this.analysisSession,
    AnalysisOptionsImpl analysisOptions,
    SourceFactory sourceFactory,
    DeclaredVariables declaredVariables,
  ) {
    var synchronousSession =
        SynchronousSession(analysisOptions, declaredVariables);
    analysisContext = AnalysisContextImpl(
      synchronousSession,
      sourceFactory,
    );

    _createElementFactory();
  }

  /// Load data required to access elements of the given [targetLibrary].
  void load2(FileState targetLibrary) {
    var inputBundles = <LinkedNodeBundle>[];

    var numCycles = 0;
    var librariesTotal = 0;
    var librariesLoaded = 0;
    var librariesLinked = 0;
    var librariesLinkedTimer = Stopwatch();
    var inputsTimer = Stopwatch();
    var bytesGet = 0;
    var bytesPut = 0;

    void loadBundle(LibraryCycle cycle) {
      if (!loadedBundles.add(cycle)) return;

      numCycles++;
      librariesTotal += cycle.libraries.length;

      cycle.directDependencies.forEach(loadBundle);

      var key = cycle.cyclePathsHash;
      var bytes = byteStore.get(key);

      // check to see if any of the sources have changed
      if (bytes != null) {
        var hash = CiderLinkedLibraryCycle.fromBuffer(bytes).signature;
        if (!const ListEquality().equals(hash, cycle.signature)) {
          bytes = null;
        }
      }

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

        inputsTimer.start();
        var inputLibraries = <link2.LinkInputLibrary>[];
        for (var libraryFile in cycle.libraries) {
          var librarySource = libraryFile.source;
          if (librarySource == null) continue;

          var inputUnits = <link2.LinkInputUnit>[];
          var partIndex = -1;
          for (var file in libraryFile.libraryFiles) {
            var isSynthetic = !file.exists;
            var content = '';
            try {
              content = resourceProvider.getFile(file.path).readAsStringSync();
            } catch (_) {}
            var unit = file.parse(
              AnalysisErrorListener.NULL_LISTENER,
              content,
            );

            String partUriStr;
            if (partIndex >= 0) {
              partUriStr = libraryFile.unlinked2.parts[partIndex];
            }
            partIndex++;

            inputUnits.add(
              link2.LinkInputUnit(
                partUriStr,
                file.source,
                isSynthetic,
                unit,
              ),
            );
          }

          inputLibraries.add(
            link2.LinkInputLibrary(librarySource, inputUnits),
          );
        }
        inputsTimer.stop();

        var linkResult = link2.link(elementFactory, inputLibraries);
        librariesLinked += cycle.libraries.length;

        bytes = serializeBundle(cycle.signature, linkResult).toBuffer();

        byteStore.put(key, bytes);
        bytesPut += bytes.length;

        librariesLinkedTimer.stop();
      } else {
        // TODO(scheglov) Take / clear parsed units in files.
        bytesGet += bytes.length;
        librariesLoaded += cycle.libraries.length;
      }

      // We are about to load dart:core, but if we have just linked it, the
      // linker might have set the type provider. So, clear it, and recreate
      // the element factory - it is empty anyway.
      if (!elementFactory.hasDartCore) {
        analysisContext.clearTypeProvider();
        _createElementFactory();
      }
      var cBundle = CiderLinkedLibraryCycle.fromBuffer(bytes);
      inputBundles.add(cBundle.bundle);
      elementFactory.addBundle(
        LinkedBundleContext(elementFactory, cBundle.bundle),
      );

      // Set informative data.
      for (var libraryFile in cycle.libraries) {
        for (var unitFile in libraryFile.libraryFiles) {
          elementFactory.setInformativeData(
            libraryFile.uriStr,
            unitFile.uriStr,
            unitFile.unlinked2.informativeData,
          );
        }
      }
    }

    logger.run('Prepare linked bundles', () {
      var libraryCycle = targetLibrary.libraryCycle;
      loadBundle(libraryCycle);
      logger.writeln(
        '[numCycles: $numCycles]'
        '[librariesTotal: $librariesTotal]'
        '[librariesLoaded: $librariesLoaded]'
        '[inputsTimer: ${inputsTimer.elapsedMilliseconds} ms]'
        '[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();
    inheritanceManager = InheritanceManager3();
  }

  void _createElementFactory() {
    elementFactory = LinkedElementFactory(
      analysisContext,
      analysisSession,
      Reference.root(),
    );
  }

  /// Ensure that type provider is created.
  void _createElementFactoryTypeProvider() {
    if (analysisContext.typeProviderNonNullableByDefault == null) {
      var dartCore = elementFactory.libraryOfUri('dart:core');
      var dartAsync = elementFactory.libraryOfUri('dart:async');
      elementFactory.createTypeProviders(dartCore, dartAsync);
    }
  }

  static CiderLinkedLibraryCycleBuilder serializeBundle(
      List<int> signature, link2.LinkResult linkResult) {
    return CiderLinkedLibraryCycleBuilder(
      signature: signature,
      bundle: linkResult.bundle,
    );
  }
}
