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

import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/dart/element/element.dart' show CompilationUnitElement;
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/analysis/frontend_resolution.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/kernel/resynthesize.dart';
import 'package:front_end/src/base/performance_logger.dart';
import 'package:kernel/ast.dart' as kernel;
import 'package:kernel/text/ast_to_text.dart' as kernel;

/**
 * Support for resynthesizing element model from Kernel.
 */
class KernelContext {
  static const DEBUG = false;

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

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

  KernelContext._(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 [KernelContext].
   *
   * Should be called once the [KernelContext] is no longer needed.
   */
  void dispose() {
    analysisContext.dispose();
  }

  /**
   * Return `true` if the given [uri] is known to be a library.
   */
  bool isLibraryUri(Uri uri) {
    // TODO(scheglov) implement
    return true;
//    String uriStr = uri.toString();
//    return store.unlinkedMap[uriStr]?.isPartOf == false;
  }

  /**
   * Create a [KernelContext] which is prepared to analyze [targetLibrary].
   */
  static Future<KernelContext> forSingleLibrary(
      FileState targetLibrary,
      PerformanceLog logger,
      AnalysisOptions analysisOptions,
      DeclaredVariables declaredVariables,
      SourceFactory sourceFactory,
      FileSystemState fsState,
      FrontEndCompiler compiler) async {
    // TODO(brianwilkerson) Determine whether this await is necessary.
    await null;
    return logger.runAsync('Create kernel context', () async {
      // TODO(brianwilkerson) Determine whether this await is necessary.
      await null;
      Uri targetUri = targetLibrary.uri;
      LibraryCompilationResult compilationResult =
          await compiler.compile(targetUri);

      // Remember Kernel libraries produced by the compiler.
      // There might be more libraries than we actually need.
      // This is probably OK, because we consume them lazily.
      var libraryMap = <String, kernel.Library>{};
      var libraryExistMap = <String, bool>{};
      bool coreFound = false;
      for (var library in compilationResult.component.libraries) {
        String uriStr = library.importUri.toString();
        if (uriStr == 'dart:core') {
          coreFound = true;
        }
        libraryMap[uriStr] = library;
        FileState file = fsState.getFileForUri(library.importUri);
        libraryExistMap[uriStr] = file?.exists ?? false;
      }
      if (!coreFound) {
        throw new StateError('No dart:core library found (dartbug.com/33686)');
      }

      if (DEBUG) {
        print('----------- ${targetLibrary.uriStr}');
        var libraryKernel = libraryMap[targetLibrary.uriStr];
        print(_getLibraryText(libraryKernel));
        print('--------------------------------------');
      }

      // Create and configure a new context.
      AnalysisContextImpl analysisContext =
          AnalysisEngine.instance.createAnalysisContext();
      analysisContext.useSdkCachePartition = false;
      analysisContext.analysisOptions = analysisOptions;
      analysisContext.declaredVariables = declaredVariables;
      analysisContext.sourceFactory = sourceFactory.clone();
      analysisContext.contentCache = new _ContentCacheWrapper(fsState);

      // Create the resynthesizer bound to the analysis context.
      var resynthesizer = new KernelResynthesizer(analysisContext,
          compilationResult.types, libraryMap, libraryExistMap);

      return new KernelContext._(analysisContext, resynthesizer);
    });
  }

  static String _getLibraryText(kernel.Library library) {
    StringBuffer buffer = new StringBuffer();
    new kernel.Printer(buffer, syntheticNames: new kernel.NameSystem())
        .writeLibraryFile(library);
    return buffer.toString();
  }
}

/**
 * [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) {
    return _getFileForSource(source).exists;
  }

  @override
  int getModificationStamp(Source source) {
    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);
  }
}
