// 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 'package:analyzer/context/declared_variables.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart'
    show CompilationUnitElement, LibraryElement;
import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/handle.dart';
import 'package:analyzer/src/generated/engine.dart'
    show AnalysisContext, AnalysisEngine, AnalysisOptions;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/link.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:front_end/src/base/performace_logger.dart';
import 'package:front_end/src/byte_store/byte_store.dart';

/**
 * Context information necessary to analyze one or more libraries within an
 * [AnalysisDriver].
 *
 * Currently this is implemented as a wrapper around [AnalysisContext].
 * TODO(paulberry): make a front end API that this can make use of instead.
 */
class LibraryContext {
  final SummaryDataStore store;

  /**
   * The [AnalysisContext] which is used to do the analysis.
   */
  final AnalysisContext _analysisContext;

  /**
   * The resynthesizer that resynthesizes elements in [_analysisContext].
   */
  final ElementResynthesizer _resynthesizer;

  /**
   * Create a [LibraryContext] which is prepared to analyze [targetLibrary].
   */
  factory LibraryContext.forSingleLibrary(
      FileState targetLibrary,
      PerformanceLog logger,
      PackageBundle sdkBundle,
      ByteStore byteStore,
      AnalysisOptions options,
      DeclaredVariables declaredVariables,
      SourceFactory sourceFactory,
      SummaryDataStore externalSummaries,
      FileSystemState fsState) {
    return logger.run('Create library context', () {
      Map<String, FileState> libraries = <String, FileState>{};
      SummaryDataStore store = new SummaryDataStore(const <String>[]);

      if (externalSummaries != null) {
        store.addStore(externalSummaries);
      }

      if (sdkBundle != null) {
        store.addBundle(null, sdkBundle);
      }

      void appendLibraryFiles(FileState library) {
        if (!libraries.containsKey(library.uriStr)) {
          // Serve 'dart:' URIs from the SDK bundle.
          if (sdkBundle != null && library.uri.scheme == 'dart') {
            return;
          }

          if (library.isInExternalSummaries) {
            return;
          }

          libraries[library.uriStr] = library;

          // Append the defining unit.
          store.addUnlinkedUnit(library.uriStr, library.unlinked);

          // Append parts.
          for (FileState part in library.partedFiles) {
            store.addUnlinkedUnit(part.uriStr, part.unlinked);
          }

          // Append referenced libraries.
          library.importedFiles.forEach(appendLibraryFiles);
          library.exportedFiles.forEach(appendLibraryFiles);
        }
      }

      logger.run('Append library files', () {
        return appendLibraryFiles(targetLibrary);
      });

      Set<String> libraryUrisToLink = new Set<String>();
      logger.run('Load linked bundles', () {
        for (FileState library in libraries.values) {
          if (library.exists || library == targetLibrary) {
            String key = '${library.transitiveSignature}.linked';
            List<int> bytes = byteStore.get(key);
            if (bytes != null) {
              LinkedLibrary linked = new LinkedLibrary.fromBuffer(bytes);
              store.addLinkedLibrary(library.uriStr, linked);
            } else {
              libraryUrisToLink.add(library.uriStr);
            }
          }
        }
        int numOfLoaded = libraries.length - libraryUrisToLink.length;
        logger.writeln('Loaded $numOfLoaded linked bundles.');
      });

      Map<String, LinkedLibraryBuilder> linkedLibraries = {};
      logger.run('Link bundles', () {
        linkedLibraries = link(libraryUrisToLink, (String uri) {
          LinkedLibrary linkedLibrary = store.linkedMap[uri];
          return linkedLibrary;
        }, (String uri) {
          UnlinkedUnit unlinkedUnit = store.unlinkedMap[uri];
          return unlinkedUnit;
        }, (_) => null, options.strongMode);
        logger.writeln('Linked ${linkedLibraries.length} bundles.');
      });

      linkedLibraries.forEach((uri, linkedBuilder) {
        FileState library = libraries[uri];
        String key = '${library.transitiveSignature}.linked';
        List<int> bytes = linkedBuilder.toBuffer();
        LinkedLibrary linked = new LinkedLibrary.fromBuffer(bytes);
        store.addLinkedLibrary(uri, linked);
        byteStore.put(key, bytes);
      });

      var resynthesizingContext = _createResynthesizingContext(
          options, declaredVariables, sourceFactory, store);
      resynthesizingContext.context.contentCache =
          new _ContentCacheWrapper(fsState);

      return new LibraryContext._(store, resynthesizingContext.context,
          resynthesizingContext.resynthesizer);
    });
  }

  LibraryContext._(this.store, this._analysisContext, this._resynthesizer);

  /**
   * Computes a [CompilationUnitElement] for the given library/unit pair.
   */
  CompilationUnitElement computeUnitElement(
      Source librarySource, Source unitSource) {
    String libraryUri = librarySource.uri.toString();
    String unitUri = unitSource.uri.toString();
    return _resynthesizer.getElement(
        new ElementLocationImpl.con3(<String>[libraryUri, unitUri]));
  }

  /**
   * Cleans up any persistent resources used by this [LibraryContext].
   *
   * Should be called once the [LibraryContext] is no longer needed.
   */
  void dispose() {
    _analysisContext.dispose();
  }

  /**
   * Resynthesize the [LibraryElement] from the given [store].
   */
  static LibraryElement resynthesizeLibraryElement(
      AnalysisOptions analysisOptions,
      DeclaredVariables declaredVariables,
      SourceFactory sourceFactory,
      SummaryDataStore store,
      String uri) {
    var resynthesizingContext = _createResynthesizingContext(
        analysisOptions, declaredVariables, sourceFactory, store);
    try {
      return resynthesizingContext.resynthesizer
          .getElement(new ElementLocationImpl.con3([uri]));
    } finally {
      resynthesizingContext.context.dispose();
    }
  }

  static _ResynthesizingAnalysisContext _createResynthesizingContext(
      AnalysisOptions analysisOptions,
      DeclaredVariables declaredVariables,
      SourceFactory sourceFactory,
      SummaryDataStore store) {
    AnalysisContextImpl analysisContext =
        AnalysisEngine.instance.createAnalysisContext();
    analysisContext.useSdkCachePartition = false;
    analysisContext.analysisOptions = analysisOptions;
    analysisContext.declaredVariables.addAll(declaredVariables);
    analysisContext.sourceFactory = sourceFactory.clone();
    var provider = new InputPackagesResultProvider(analysisContext, store);
    analysisContext.resultProvider = provider;
    return new _ResynthesizingAnalysisContext(
        analysisContext, provider.resynthesizer);
  }
}

/**
 * Container object holding the result of a call to
 * [LibraryContext.resolveUnit].
 */
class ResolutionResult {
  final CompilationUnit resolvedUnit;
  final List<AnalysisError> errors;

  ResolutionResult(this.resolvedUnit, this.errors);
}

/**
 * [ContentCache] wrapper around [FileContentOverlay].
 */
class _ContentCacheWrapper implements ContentCache {
  final FileSystemState fsState;

  _ContentCacheWrapper(this.fsState);

  @override
  void accept(ContentCacheVisitor visitor) {
    throw new UnimplementedError();
  }

  @override
  String getContents(Source source) {
    return _getFileForSource(source).content;
  }

  @override
  bool getExists(Source source) {
    if (source.isInSystemLibrary) {
      return true;
    }
    String uriStr = source.uri.toString();
    if (fsState.externalSummaries.hasUnlinkedUnit(uriStr)) {
      return true;
    }
    return _getFileForSource(source).exists;
  }

  @override
  int getModificationStamp(Source source) {
    if (source.isInSystemLibrary) {
      return 0;
    }
    return _getFileForSource(source).exists ? 0 : -1;
  }

  @override
  String setContents(Source source, String contents) {
    throw new UnimplementedError();
  }

  FileState _getFileForSource(Source source) {
    String path = source.fullName;
    return fsState.getFileForPath(path);
  }
}

/**
 * Container with analysis context and the corresponding resynthesizer.
 */
class _ResynthesizingAnalysisContext {
  final AnalysisContextImpl context;
  final ElementResynthesizer resynthesizer;

  _ResynthesizingAnalysisContext(this.context, this.resynthesizer);
}
