// Copyright (c) 2019, 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.

// TODO(paulberry,johnniwinther): Use the code for extraction of test data from
// annotated code from CFE.

import 'package:_fe_analyzer_shared/src/testing/annotated_code_helper.dart';
import 'package:_fe_analyzer_shared/src/testing/id.dart';
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:analyzer/dart/ast/ast.dart' hide Annotation;
import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/src/dart/analysis/testing_data.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';

/// Test configuration used for testing the analyzer without experiments.
final TestConfig analyzerDefaultConfig = TestConfig(
    analyzerMarker, 'analyzer without experiments',
    featureSet: FeatureSet.latestLanguageVersion());

/// A fake absolute directory used as the root of a memory-file system in ID
/// tests.
Uri _defaultDir = Uri.parse('file:///a/b/c/');

/// Creates the testing URI used for [fileName] in annotated tests.
Uri createUriForFileName(String fileName) => _toTestUri(fileName);

void onFailure(String message) {
  throw StateError(message);
}

/// Runs [dataComputer] on [testData] for all [testedConfigs].
///
/// Returns `true` if an error was encountered.
Future<Map<String, TestResult<T>>> runTest<T>(
    MarkerOptions markerOptions,
    TestData testData,
    DataComputer<T> dataComputer,
    List<TestConfig> testedConfigs,
    {required bool testAfterFailures,
    bool forUserLibrariesOnly = true,
    Iterable<Id> globalIds = const <Id>[],
    required void Function(String message) onFailure,
    Map<String, List<String>>? skipMap}) async {
  for (TestConfig config in testedConfigs) {
    if (!testData.expectedMaps.containsKey(config.marker)) {
      throw ArgumentError("Unexpected test marker '${config.marker}'. "
          "Supported markers: ${testData.expectedMaps.keys}.");
    }
  }

  Map<String, TestResult<T>> results = {};
  for (TestConfig config in testedConfigs) {
    if (skipForConfig(testData.name, config.marker, skipMap)) {
      continue;
    }
    results[config.marker] = await runTestForConfig(
        markerOptions, testData, dataComputer, config,
        fatalErrors: !testAfterFailures, onFailure: onFailure);
  }
  return results;
}

/// Creates a test runner for [dataComputer] on [testedConfigs].
RunTestFunction<T> runTestFor<T>(
    DataComputer<T> dataComputer, List<TestConfig> testedConfigs) {
  return (MarkerOptions markerOptions, TestData testData,
      {required bool testAfterFailures,
      bool? verbose,
      bool? succinct,
      bool? printCode,
      Map<String, List<String>>? skipMap,
      Uri? nullUri}) {
    return runTest(markerOptions, testData, dataComputer, testedConfigs,
        testAfterFailures: testAfterFailures,
        onFailure: onFailure,
        skipMap: skipMap);
  };
}

/// Runs [dataComputer] on [testData] for [config].
///
/// Returns `true` if an error was encountered.
Future<TestResult<T>> runTestForConfig<T>(MarkerOptions markerOptions,
    TestData testData, DataComputer<T> dataComputer, TestConfig config,
    {bool fatalErrors = true,
    required void Function(String message) onFailure,
    Map<String, List<String>>? skipMap}) async {
  MemberAnnotations<IdValue> memberAnnotations =
      testData.expectedMaps[config.marker]!;

  final resourceProvider = MemoryResourceProvider();
  final testFiles = <_TestFile>[];
  for (final entry in testData.memorySourceFiles.entries) {
    final uri = _toTestUri(entry.key);
    final path = resourceProvider.convertPath(uri.path);
    final file = resourceProvider.getFile(path);
    testFiles.add(
      _TestFile(uri: uri, file: file),
    );
    file.writeAsStringSync(entry.value);
  }

  final sdkRoot = resourceProvider.newFolder(
    resourceProvider.convertPath('/sdk'),
  );
  createMockSdk(
    resourceProvider: resourceProvider,
    root: sdkRoot,
  );

  final contextCollection = AnalysisContextCollectionImpl(
    includedPaths: testFiles.map((e) => e.path).toList(),
    resourceProvider: resourceProvider,
    retainDataForTesting: true,
    sdkPath: sdkRoot.path,
  );
  final analysisContext = contextCollection.contexts.single;
  final analysisSession = analysisContext.currentSession;
  final driver = analysisContext.driver;

  Map<Uri, Map<Id, ActualData<T>>> actualMaps = <Uri, Map<Id, ActualData<T>>>{};
  Map<Id, ActualData<T>> globalData = <Id, ActualData<T>>{};

  Map<Id, ActualData<T>> actualMapFor(Uri uri) {
    return actualMaps.putIfAbsent(uri, () => <Id, ActualData<T>>{});
  }

  var results = <Uri, ResolvedUnitResult>{};
  for (final testFile in testFiles) {
    final testUri = testFile.uri;
    final result = await analysisSession.getResolvedUnit(testFile.path);
    result as ResolvedUnitResult;
    var errors =
        result.errors.where((e) => e.severity == Severity.error).toList();
    if (errors.isNotEmpty) {
      if (dataComputer.supportsErrors) {
        var errorMap = <int, List<AnalysisError>>{};
        for (var error in errors) {
          var offset = error.offset;
          if (offset == 0 || offset < 0) {
            // Position errors without offset in the begin of the file.
            offset = 0;
          }
          (errorMap[offset] ??= <AnalysisError>[]).add(error);
        }
        errorMap.forEach((offset, errors) {
          var id = NodeId(offset, IdKind.error);
          var data = dataComputer.computeErrorData(
              config, driver.testingData!, id, errors);
          if (data != null) {
            Map<Id, ActualData<T>> actualMap = actualMapFor(testUri);
            actualMap[id] = ActualData<T>(id, data, testUri, offset, errors);
          }
        });
      } else {
        String formatError(AnalysisError e) {
          var locationInfo = result.unit.lineInfo.getLocation(e.offset);
          return '$locationInfo: ${e.errorCode}: ${e.message}';
        }

        onFailure('Errors found:\n  ${errors.map(formatError).join('\n  ')}');
        return TestResult<T>.erroneous();
      }
    }
    results[testUri] = result;
  }

  results.forEach((testUri, result) {
    dataComputer.computeUnitData(
        driver.testingData!, result.unit, actualMapFor(testUri));
  });
  var compiledData = AnalyzerCompiledData<T>(
      testData.code, testData.entryPoint, actualMaps, globalData);
  return checkCode(markerOptions, config.marker, config.name, testData,
      memberAnnotations, compiledData, dataComputer.dataValidator,
      fatalErrors: fatalErrors, onFailure: onFailure);
}

/// Convert relative file paths into an absolute Uri as expected by the test
/// helpers.
Uri _toTestUri(String relativePath) => _defaultDir.resolve(relativePath);

class AnalyzerCompiledData<T> extends CompiledData<T> {
  // TODO(johnniwinther,paulberry): Maybe this should have access to the
  // [ResolvedUnitResult] instead.
  final Map<Uri, AnnotatedCode> code;

  AnalyzerCompiledData(
      this.code,
      Uri mainUri,
      Map<Uri, Map<Id, ActualData<T>>> actualMaps,
      Map<Id, ActualData<T>> globalData)
      : super(mainUri, actualMaps, globalData);

  @override
  int getOffsetFromId(Id id, Uri uri) {
    if (id is NodeId) {
      return id.value;
    } else if (id is MemberId) {
      var className = id.className;
      var name = id.memberName;
      var unit =
          parseString(content: code[uri]!.sourceCode, throwIfDiagnostics: false)
              .unit;
      if (className != null) {
        for (var declaration in unit.declarations) {
          if (declaration is ClassDeclaration &&
              declaration.name2.lexeme == className) {
            for (var member in declaration.members) {
              if (member is ConstructorDeclaration) {
                if (member.name2!.lexeme == name) {
                  return member.offset;
                }
              } else if (member is FieldDeclaration) {
                for (var variable in member.fields.variables) {
                  if (variable.name2.lexeme == name) {
                    return variable.offset;
                  }
                }
              } else if (member is MethodDeclaration) {
                if (member.name2.lexeme == name) {
                  return member.offset;
                }
              }
            }
            // Use class offset for members not declared in the class.
            return declaration.offset;
          }
        }
        return 0;
      }
      for (var declaration in unit.declarations) {
        if (declaration is FunctionDeclaration) {
          if (declaration.name2.lexeme == name) {
            return declaration.offset;
          }
        } else if (declaration is TopLevelVariableDeclaration) {
          for (var variable in declaration.variables.variables) {
            if (variable.name2.lexeme == name) {
              return variable.offset;
            }
          }
        }
      }
      return 0;
    } else if (id is ClassId) {
      var className = id.className;
      var unit =
          parseString(content: code[uri]!.sourceCode, throwIfDiagnostics: false)
              .unit;
      for (var declaration in unit.declarations) {
        if (declaration is ClassDeclaration &&
            declaration.name2.lexeme == className) {
          return declaration.offset;
        }
      }
      return 0;
    } else if (id is LibraryId) {
      var unit =
          parseString(content: code[uri]!.sourceCode, throwIfDiagnostics: false)
              .unit;
      var offset = unit.declaredElement?.library.nameOffset ?? -1;
      return offset >= 0 ? offset : 0;
    } else {
      throw StateError('Unexpected id ${id.runtimeType}');
    }
  }

  @override
  void reportError(Uri uri, int offset, String message,
      {bool succinct = false}) {
    print('$offset: $message');
  }
}

abstract class DataComputer<T> {
  const DataComputer();

  DataInterpreter<T> get dataValidator;

  /// Returns `true` if this data computer supports tests with compile-time
  /// errors.
  ///
  /// Unsuccessful compilation might leave the compiler in an inconsistent
  /// state, so this testing feature is opt-in.
  bool get supportsErrors => false;

  /// Returns data corresponding to [error].
  T? computeErrorData(TestConfig config, TestingData testingData, Id id,
          List<AnalysisError> errors) =>
      null;

  /// Function that computes a data mapping for [unit].
  ///
  /// Fills [actualMap] with the data and [sourceSpanMap] with the source spans
  /// for the data origin.
  void computeUnitData(TestingData testingData, CompilationUnit unit,
      Map<Id, ActualData<T>> actualMap);
}

class TestConfig {
  final String marker;
  final String name;
  final FeatureSet featureSet;

  TestConfig(this.marker, this.name, {FeatureSet? featureSet})
      : featureSet = featureSet ?? FeatureSet.latestLanguageVersion();
}

class _TestFile {
  final Uri uri;
  final File file;

  _TestFile({
    required this.uri,
    required this.file,
  });

  String get path => file.path;
}
