// 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.

import 'dart:io';

import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/lint/registry.dart';
import 'package:analyzer/src/string_source.dart';
import 'package:linter/src/rules.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';

void main() {
  // Set prefix for local or bot execution.
  final pathPrefix =
      FileSystemEntity.isDirectorySync(path.join('test', 'integration'))
          ? ''
          : path.join('pkg', 'analysis_server');

  /// Ensure server lint name representations correspond w/ actual lint rules.
  /// See, e.g., https://dart-review.googlesource.com/c/sdk/+/95743.
  group('lint_names', () {
    var fixFileContents = File(path.join(
            pathPrefix, 'lib', 'src', 'services', 'linter', 'lint_names.dart'))
        .readAsStringSync();
    var parser = CompilationUnitParser();
    var cu = parser.parse(contents: fixFileContents, name: 'lint_names.dart');
    var lintNamesClass = cu.declarations
        .firstWhere((m) => m is ClassDeclaration && m.name.name == 'LintNames');

    var collector = _FixCollector();
    lintNamesClass.accept(collector);
    for (var name in collector.lintNames) {
      test(name, () {
        expect(registeredLintNames, contains(name));
      });
    }
  });
}

List<LintRule>? _registeredLints;

Iterable<String> get registeredLintNames => registeredLints.map((r) => r.name);

List<LintRule> get registeredLints {
  var registeredLints = _registeredLints;
  if (registeredLints == null) {
    if (Registry.ruleRegistry.isEmpty) {
      registerLintRules();
    }
    registeredLints = Registry.ruleRegistry.toList();
    _registeredLints = registeredLints;
  }
  return registeredLints;
}

class CompilationUnitParser {
  CompilationUnit parse({required String contents, required String name}) {
    var reader = CharSequenceReader(contents);
    var stringSource = StringSource(contents, name);
    var errorListener = _ErrorListener();
    var featureSet = FeatureSet.forTesting(sdkVersion: '2.2.2');
    var scanner = Scanner(stringSource, reader, errorListener)
      ..configureFeatures(
        featureSetForOverriding: featureSet,
        featureSet: featureSet,
      );
    var startToken = scanner.tokenize();
    errorListener.throwIfErrors();

    var parser = Parser(
      stringSource,
      errorListener,
      featureSet: featureSet,
    );
    var cu = parser.parseCompilationUnit(startToken);
    errorListener.throwIfErrors();

    return cu;
  }
}

class _ErrorListener implements AnalysisErrorListener {
  final errors = <AnalysisError>[];

  @override
  void onError(AnalysisError error) {
    errors.add(error);
  }

  void throwIfErrors() {
    if (errors.isNotEmpty) {
      throw Exception(errors);
    }
  }
}

class _FixCollector extends GeneralizingAstVisitor<void> {
  final List<String> lintNames = <String>[];

  @override
  void visitFieldDeclaration(FieldDeclaration node) {
    for (var v in node.fields.variables) {
      lintNames.add(v.name.name);
    }
  }
}
