// Copyright (c) 2015, 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:io';

import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/lint/io.dart';
import 'package:analyzer/src/lint/registry.dart';
import 'package:analyzer/src/services/lint.dart' as lint_service;
import 'package:analyzer/src/task/options.dart';
import 'package:linter/src/analyzer.dart';
import 'package:linter/src/ast.dart';
import 'package:linter/src/formatter.dart';
import 'package:linter/src/rules.dart';
import 'package:linter/src/rules/implementation_imports.dart';
import 'package:linter/src/rules/package_prefixed_library_names.dart';
import 'package:linter/src/test_utilities/annotation.dart';
import 'package:linter/src/test_utilities/test_resource_provider.dart';
import 'package:linter/src/version.dart';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';

import 'experiments_test.dart' as experiment_tests;
import 'test_constants.dart';
import 'util/annotation_matcher.dart';
import 'util/test_utils.dart';

void main() {
  defineSanityTests();
  defineRuleTests();
  experiment_tests.main();
  defineRuleUnitTests();
}

/// Rule tests
void defineRuleTests() {
  group('rule', () {
    group('dart', () {
      // Rule tests run with default analysis options.
      testRules(ruleTestDir);

      // Rule tests run against specific configurations.
      for (var entry in Directory(testConfigDir).listSync()) {
        if (entry is! Directory) continue;
        group('(config: ${p.basename(entry.path)})', () {
          var analysisOptionsFile =
              File(p.join(entry.path, 'analysis_options.yaml'));
          var analysisOptions = analysisOptionsFile.readAsStringSync();
          testRules(ruleTestDir, analysisOptions: analysisOptions);
        });
      }
    });
    group('pub', () {
      for (var entry in Directory(p.join(ruleTestDir, 'pub')).listSync()) {
        if (entry is Directory) {
          for (var child in entry.listSync()) {
            if (child is File && isPubspecFile(child)) {
              var ruleName = p.basename(entry.path);
              testRule(ruleName, child);
            }
          }
        }
      }
    });
    group('format', () {
      for (var rule in Registry.ruleRegistry.rules) {
        test('`${rule.name}` description', () {
          expect(rule.description.endsWith('.'), isTrue,
              reason:
                  "Rule description for ${rule.name} should end with a '.'");
        });
      }
    });
  });
}

void defineRuleUnitTests() {
  group('uris', () {
    group('isPackage', () {
      for (var uri in [
        Uri.parse('package:foo/src/bar.dart'),
        Uri.parse('package:foo/src/baz/bar.dart')
      ]) {
        test(uri.toString(), () {
          expect(isPackage(uri), isTrue);
        });
      }
      for (var uri in [
        Uri.parse('foo/bar.dart'),
        Uri.parse('src/bar.dart'),
        Uri.parse('dart:async')
      ]) {
        test(uri.toString(), () {
          expect(isPackage(uri), isFalse);
        });
      }
    });

    group('samePackage', () {
      test('identity', () {
        expect(
            samePackage(Uri.parse('package:foo/src/bar.dart'),
                Uri.parse('package:foo/src/bar.dart')),
            isTrue);
      });
      test('foo/bar.dart', () {
        expect(
            samePackage(Uri.parse('package:foo/src/bar.dart'),
                Uri.parse('package:foo/bar.dart')),
            isTrue);
      });
    });

    group('implementation', () {
      for (var uri in [
        Uri.parse('package:foo/src/bar.dart'),
        Uri.parse('package:foo/src/baz/bar.dart')
      ]) {
        test(uri.toString(), () {
          expect(isImplementation(uri), isTrue);
        });
      }
      for (var uri in [
        Uri.parse('package:foo/bar.dart'),
        Uri.parse('src/bar.dart')
      ]) {
        test(uri.toString(), () {
          expect(isImplementation(uri), isFalse);
        });
      }
    });
  });

  group('names', () {
    group('keywords', () {
      var good = ['class', 'if', 'assert', 'catch', 'import'];
      testEach(good, isKeyWord, isTrue);
      var bad = ['_class', 'iff', 'assert_', 'Catch'];
      testEach(bad, isKeyWord, isFalse);
    });
    group('identifiers', () {
      var good = [
        'foo',
        '_if',
        '_',
        'f2',
        'fooBar',
        'foo_bar',
        '\$foo',
        'foo\$Bar',
        'foo\$'
      ];
      testEach(good, isValidDartIdentifier, isTrue);
      var bad = ['if', '42', '3', '2f'];
      testEach(bad, isValidDartIdentifier, isFalse);
    });
    group('library_name_prefixes', () {
      bool isGoodPrefix(List<String> v) => matchesOrIsPrefixedBy(
          v[3],
          Analyzer.facade.createLibraryNamePrefix(
              libraryPath: v[0], projectRoot: v[1], packageName: v[2]));

      var good = [
        ['/u/b/c/lib/src/a.dart', '/u/b/c', 'acme', 'acme.src.a'],
        ['/u/b/c/lib/a.dart', '/u/b/c', 'acme', 'acme.a'],
        ['/u/b/c/test/a.dart', '/u/b/c', 'acme', 'acme.test.a'],
        ['/u/b/c/test/data/a.dart', '/u/b/c', 'acme', 'acme.test.data.a'],
        ['/u/b/c/lib/acme.dart', '/u/b/c', 'acme', 'acme']
      ];
      testEach(good, isGoodPrefix, isTrue);

      var bad = [
        ['/u/b/c/lib/src/a.dart', '/u/b/c', 'acme', 'acme.a'],
        ['/u/b/c/lib/a.dart', '/u/b/c', 'acme', 'wrk.acme.a'],
        ['/u/b/c/test/a.dart', '/u/b/c', 'acme', 'acme.a'],
        ['/u/b/c/test/data/a.dart', '/u/b/c', 'acme', 'acme.test.a']
      ];
      testEach(bad, isGoodPrefix, isFalse);
    });
  });
}

/// Test framework sanity.
void defineSanityTests() {
  group('reporting', () {
    // https://github.com/dart-lang/linter/issues/193
    group('ignore synthetic nodes', () {
      var path =
          p.join('test_data', 'integration', 'synthetic', 'synthetic.dart');
      var file = File(path);
      testRule('non_constant_identifier_names', file);
    });
  });

  test('linter version caching', () {
    expect(lint_service.linterVersion, version);
  });
}

/// Handy for debugging.
void defineSoloRuleTest(String ruleToTest) {
  for (var entry in Directory(ruleTestDir).listSync()) {
    if (entry is! File || !isDartFile(entry)) continue;
    var ruleName = p.basenameWithoutExtension(entry.path);
    if (ruleName == ruleToTest) {
      testRule(ruleName, entry);
    }
  }
}

void testRule(String ruleName, File file,
    {bool debug = true, String? analysisOptions}) {
  test(ruleName, () async {
    if (!file.existsSync()) {
      throw Exception('No rule found defined at: ${file.path}');
    }

    registerLintRules(inTestMode: debug);

    var expected = <AnnotationMatcher>[];

    var lineNumber = 1;
    for (var line in file.readAsLinesSync()) {
      var annotation = extractAnnotation(lineNumber, line);
      if (annotation != null) {
        expected.add(AnnotationMatcher(annotation));
      }
      ++lineNumber;
    }

    var rule = Registry.ruleRegistry[ruleName];
    if (rule == null) {
      fail('rule `$ruleName` is not registered; unable to test.');
    }

    var driver = buildDriver(rule, file, analysisOptions: analysisOptions);

    var lints = await driver.lintFiles([file]);

    var actual = <Annotation>[];
    for (var info in lints) {
      for (var error in info.errors) {
        if (error.errorCode.type == ErrorType.LINT) {
          actual.add(Annotation.forError(error, info.lineInfo));
        }
      }
    }
    actual.sort();
    try {
      expect(actual, unorderedMatches(expected));
      // ignore: avoid_catches_without_on_clauses
    } catch (_) {
      if (debug) {
        // Dump results for debugging purposes.

        // AST
        var optionsProvider = AnalysisOptionsProvider();
        var optionMap = optionsProvider.getOptionsFromString(analysisOptions);
        var optionsImpl = AnalysisOptionsImpl();
        applyToAnalysisOptions(optionsImpl, optionMap);
        var featureSet = optionsImpl.contextFeatures;
        Spelunker(file.absolute.path, featureSet: featureSet).spelunk();
        print('');
        // Lints.
        ResultReporter(lints).write();
      }

      // Rethrow and fail.
      rethrow;
    }
  });
}

void testRules(String ruleDir, {String? analysisOptions}) {
  for (var entry in Directory(ruleDir).listSync()) {
    if (entry is! File || !isDartFile(entry)) continue;
    var ruleName = p.basenameWithoutExtension(entry.path);
    if (ruleName == 'unnecessary_getters') {
      // Disabled pending fix: https://github.com/dart-lang/linter/issues/23
      continue;
    }
    testRule(ruleName, entry, analysisOptions: analysisOptions);
  }
}

/// A [LintFilter] that filters no lint.
class NoFilter implements LintFilter {
  @override
  bool filter(AnalysisError lint) => false;
}

/// A [DetailedReporter] that filters no lint, only used in debug mode, when
/// actual lints do not match expectations.
class ResultReporter extends DetailedReporter {
  ResultReporter(Iterable<AnalysisErrorInfo> errors)
      : super(errors, NoFilter(), stdout);
}
