// 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 'package:analyzer/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';

/// Helper class to test that `test_all.dart` files are properly set up in the
/// `analyzer` package (and related packages).
class VerifyTests {
  /// Path to the package's `test` subdirectory.
  final String testDirPath;

  /// Paths to exclude from analysis completely.
  final List<String>? excludedPaths;

  VerifyTests(this.testDirPath, {this.excludedPaths});

  /// Build tests.
  void build() {
    var provider = PhysicalResourceProvider.INSTANCE;
    var collection = AnalysisContextCollection(
        resourceProvider: provider,
        includedPaths: <String>[testDirPath],
        excludedPaths: excludedPaths);
    var contexts = collection.contexts;
    if (contexts.length != 1) {
      fail('The test directory contains multiple analysis contexts.');
    }

    _buildTestsIn(contexts[0].currentSession, testDirPath,
        provider.getFolder(testDirPath));
  }

  /// May be overridden in a derived class to indicate whether the test file or
  /// directory indicated by [resource] is so expensive to run that it shouldn't
  /// be included in `test_all.dart` files.
  ///
  /// Default behavior is not to consider any test files or directories
  /// expensive.
  bool isExpensive(Resource resource) => false;

  /// May be overridden in a derived class to indicate whether it is ok for a
  /// `test_all.dart` file in [folder] to import [uri], even if there is no
  /// corresponding test file inside [folder].
  ///
  /// Default behavior is to allow imports of test framework URIs.
  bool isOkAsAdditionalTestAllImport(Folder folder, String uri) => const [
        'package:test/test.dart',
        'package:test_reflective_loader/test_reflective_loader.dart'
      ].contains(uri);

  /// May be overridden in a derived class to indicate whether it is ok for
  /// a `test_all.dart` file to be missing from [folder].
  ///
  /// Default beahvior is not to allow `test_all.dart` to be missing from any
  /// folder.
  bool isOkForTestAllToBeMissing(Folder folder) => false;

  void _buildTestsIn(
      AnalysisSession session, String testDirPath, Folder directory) {
    var testFileNames = <String>[];
    File? testAllFile;
    var children = directory.getChildren();
    children
        .sort((first, second) => first.shortName.compareTo(second.shortName));
    for (var child in children) {
      if (child is Folder) {
        if (child.getChildAssumingFile('test_all.dart').exists &&
            !isExpensive(child)) {
          testFileNames.add('${child.shortName}/test_all.dart');
        }
        _buildTestsIn(session, testDirPath, child);
      } else if (child is File) {
        var name = child.shortName;
        if (name == 'test_all.dart') {
          testAllFile = child;
        } else if (name.endsWith('_test.dart') && !isExpensive(child)) {
          testFileNames.add(name);
        }
      }
    }
    var relativePath = path.relative(directory.path, from: testDirPath);
    test(relativePath, () async {
      if (testFileNames.isEmpty) {
        return;
      }
      if (testAllFile == null) {
        if (!isOkForTestAllToBeMissing(directory)) {
          fail('Missing "test_all.dart" in $relativePath');
        } else {
          // Ok that the `test_all.dart` file is missing; there's nothing else to
          // check.
          return;
        }
      }
      if (isOkForTestAllToBeMissing(directory)) {
        fail('Found "test_all.dart" in $relativePath but did not expect one');
      }
      var result = session.getParsedUnit(testAllFile.path);
      if (result is! ParsedUnitResult) {
        fail('Could not parse ${testAllFile.path}');
      }
      var importedFiles = <String>[];
      for (var directive in result.unit.directives) {
        if (directive is ImportDirective) {
          var uri = directive.uri.stringValue;
          if (uri == null) {
            fail('Invalid URI: $directive');
          }
          importedFiles.add(uri);
        }
      }
      var missingFiles = <String>[];
      for (var testFileName in testFileNames) {
        if (!importedFiles.contains(testFileName)) {
          missingFiles.add(testFileName);
        }
      }
      if (missingFiles.isNotEmpty) {
        fail('Tests missing from "test_all.dart": ${missingFiles.join(', ')}');
      }
      var extraImports = <String>[];
      for (var importedFile in importedFiles) {
        if (!testFileNames.contains(importedFile) &&
            !isOkAsAdditionalTestAllImport(directory, importedFile)) {
          extraImports.add(importedFile);
        }
      }
      if (extraImports.isNotEmpty) {
        fail('Extra tests in "test_all.dart": ${extraImports.join(', ')}');
      }
    });
  }
}
