// 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/analysis_context.dart';
import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/analysis/uri_converter.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/driver.dart' as driver;
import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
import 'package:analyzer/src/dart/analysis/uri_converter.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';

/**
 * A concrete implementation of an analysis session.
 */
class AnalysisSessionImpl implements AnalysisSession {
  /**
   * The analysis driver performing analysis for this session.
   */
  final driver.AnalysisDriver _driver;

  /**
   * The type provider being used by the analysis driver.
   */
  TypeProvider _typeProvider;

  /**
   * The type system being used by the analysis driver.
   */
  TypeSystem _typeSystem;

  /**
   * The URI converter used to convert between URI's and file paths.
   */
  UriConverter _uriConverter;

  /**
   * The cache of libraries for URIs.
   */
  final Map<String, LibraryElement> _uriToLibraryCache = {};

  /**
   * Initialize a newly created analysis session.
   */
  AnalysisSessionImpl(this._driver);

  @override
  AnalysisContext get analysisContext => _driver.analysisContext;

  @override
  DeclaredVariables get declaredVariables => _driver.declaredVariables;

  @override
  ResourceProvider get resourceProvider => _driver.resourceProvider;

  @override
  SourceFactory get sourceFactory => _driver.sourceFactory;

  @override
  Future<TypeProvider> get typeProvider async {
    // TODO(brianwilkerson) Determine whether this await is necessary.
    await null;
    _checkConsistency();
    if (_typeProvider == null) {
      LibraryElement coreLibrary = await _driver.getLibraryByUri('dart:core');
      LibraryElement asyncLibrary = await _driver.getLibraryByUri('dart:async');
      _typeProvider = new TypeProviderImpl(coreLibrary, asyncLibrary);
    }
    return _typeProvider;
  }

  @override
  Future<TypeSystem> get typeSystem async {
    // TODO(brianwilkerson) Determine whether this await is necessary.
    await null;
    _checkConsistency();
    if (_typeSystem == null) {
      _typeSystem = new Dart2TypeSystem(await typeProvider);
    }
    return _typeSystem;
  }

  @override
  UriConverter get uriConverter {
    return _uriConverter ??= new DriverBasedUriConverter(_driver);
  }

  @deprecated
  driver.AnalysisDriver getDriver() => _driver;

  @override
  Future<ErrorsResult> getErrors(String path) {
    _checkConsistency();
    return _driver.getErrors(path);
  }

  @override
  Future<LibraryElement> getLibraryByUri(String uri) async {
    // TODO(brianwilkerson) Determine whether this await is necessary.
    await null;
    _checkConsistency();
    var libraryElement = _uriToLibraryCache[uri];
    if (libraryElement == null) {
      libraryElement = await _driver.getLibraryByUri(uri);
      _uriToLibraryCache[uri] = libraryElement;
    }
    return libraryElement;
  }

  @deprecated
  @override
  Future<ParseResult> getParsedAst(String path) async => getParsedUnit(path);

  @deprecated
  @override
  ParseResult getParsedAstSync(String path) => getParsedUnit(path);

  @override
  ParsedLibraryResult getParsedLibrary(String path) {
    _checkConsistency();
    return _driver.getParsedLibrary(path);
  }

  @override
  ParsedLibraryResult getParsedLibraryByElement(LibraryElement element) {
    _checkConsistency();
    _checkElementOfThisSession(element);
    return _driver.getParsedLibraryByUri(element.source.uri);
  }

  @override
  ParsedUnitResult getParsedUnit(String path) {
    _checkConsistency();
    return _driver.parseFileSync(path);
  }

  @deprecated
  @override
  Future<ResolveResult> getResolvedAst(String path) => getResolvedUnit(path);

  @override
  Future<ResolvedLibraryResult> getResolvedLibrary(String path) {
    _checkConsistency();
    return _driver.getResolvedLibrary(path);
  }

  @override
  Future<ResolvedLibraryResult> getResolvedLibraryByElement(
      LibraryElement element) {
    _checkConsistency();
    _checkElementOfThisSession(element);
    return _driver.getResolvedLibraryByUri(element.source.uri);
  }

  @override
  Future<ResolvedUnitResult> getResolvedUnit(String path) {
    _checkConsistency();
    return _driver.getResult(path);
  }

  @override
  Future<SourceKind> getSourceKind(String path) {
    _checkConsistency();
    return _driver.getSourceKind(path);
  }

  @override
  Future<List<TopLevelDeclarationInSource>> getTopLevelDeclarations(
      String name) {
    _checkConsistency();
    return _driver.getTopLevelNameDeclarations(name);
  }

  @override
  Future<UnitElementResult> getUnitElement(String path) {
    _checkConsistency();
    return _driver.getUnitElement(path);
  }

  @override
  Future<String> getUnitElementSignature(String path) {
    _checkConsistency();
    return _driver.getUnitElementSignature(path);
  }

  /**
   * Check to see that results from this session will be consistent, and throw
   * an [InconsistentAnalysisException] if they might not be.
   */
  void _checkConsistency() {
    if (_driver.currentSession != this) {
      throw new InconsistentAnalysisException();
    }
  }

  void _checkElementOfThisSession(Element element) {
    if (element.session != this) {
      throw new ArgumentError(
          '(${element.runtimeType}) $element was not produced by '
          'this session.');
    }
  }
}
