// 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/source/error_processor.dart';
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:analyzer/src/util/sdk.dart';
import 'package:analyzer_cli/src/ansi.dart' as ansi;
import 'package:analyzer_cli/src/driver.dart';
import 'package:analyzer_cli/src/options.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:yaml/src/yaml_node.dart';

import 'utils.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(ExitCodesTest);
    defineReflectiveTests(LinterTest);
    defineReflectiveTests(NonDartFilesTest);
    defineReflectiveTests(OptionsTest);
  }, name: 'Driver');
}

class BaseTest {
  static const emptyOptionsFile = 'data/empty_options.yaml';

  late StringSink _savedOutSink, _savedErrorSink;
  late int _savedExitCode;
  late ExitHandler _savedExitHandler;

  late Driver driver;

  AnalysisOptions get analysisOptions => driver.analysisDriver!.analysisOptions;

  /// Normalize text with bullets.
  String bulletToDash(StringSink? item) => '$item'.replaceAll('•', '-');

  /// Start a driver for the given [source], optionally providing additional
  /// [args] and an [options] file path. The value of [options] defaults to an
  /// empty options file to avoid unwanted configuration from an otherwise
  /// discovered options file.
  Future<void> drive(
    String source, {
    String options = emptyOptionsFile,
    List<String> args = const <String>[],
  }) {
    return driveMany([source], options: options, args: args);
  }

  /// Like [drive], but takes an array of sources.
  Future<void> driveMany(
    List<String> sources, {
    String? options = emptyOptionsFile,
    List<String> args = const <String>[],
  }) async {
    options = _posixToPlatformPath(options);

    driver = Driver();
    var cmd = <String>[];
    if (options != null) {
      cmd = <String>[
        '--options',
        path.join(testDirectory, options),
      ];
    }
    cmd
      ..addAll(sources.map(_adjustFileSpec))
      ..addAll(args);

    await driver.start(cmd);
  }

  void setUp() {
    ansi.runningTests = true;
    _savedOutSink = outSink;
    _savedErrorSink = errorSink;
    _savedExitHandler = exitHandler;
    _savedExitCode = exitCode;
    exitHandler = (code) => exitCode = code;
    outSink = StringBuffer();
    errorSink = StringBuffer();
  }

  void tearDown() {
    outSink = _savedOutSink;
    errorSink = _savedErrorSink;
    exitCode = _savedExitCode;
    exitHandler = _savedExitHandler;
    ansi.runningTests = false;
  }

  /// Convert a file specification from a relative path to an absolute path.
  /// Handles the case where the file specification is of the form "$uri|$path".
  String _adjustFileSpec(String fileSpec) {
    var uriPrefixLength = fileSpec.indexOf('|') + 1;
    var uriPrefix = fileSpec.substring(0, uriPrefixLength);
    var relativePath = fileSpec.substring(uriPrefixLength);
    return '$uriPrefix${path.join(testDirectory, relativePath)}';
  }

  /// Convert the given posix [filePath] to conform to to the platform style.
  ///
  /// This is a utility method for testing; paths passed in to other methods in
  /// this class are never converted automatically.
  String? _posixToPlatformPath(String? filePath) {
    if (filePath == null) {
      return null;
    }
    if (path.style == path.windows.style) {
      filePath = filePath.replaceAll(
        path.posix.separator,
        path.windows.separator,
      );
    }
    return filePath;
  }
}

@reflectiveTest
class ExitCodesTest extends BaseTest {
  @SkippedTest(reason: 'Fails on bots, passes locally. Do not know why.')
  Future<void> test_bazelWorkspace_relativePath() async {
    // Copy to temp dir so that existing analysis options
    // in the test directory hierarchy do not interfere
    await withTempDirAsync((String tempDirPath) async {
      var dartSdkPath = path.absolute(getSdkPath());
      await recursiveCopy(
          Directory(path.join(testDirectory, 'data', 'bazel')), tempDirPath);
      var origWorkingDir = Directory.current;
      try {
        Directory.current = path.join(tempDirPath, 'proj');
        var driver = Driver();
        try {
          await driver.start([
            path.join('lib', 'file.dart'),
            '--dart-sdk',
            dartSdkPath,
          ]);
        } catch (e) {
          print('=== debug info ===');
          print('dartSdkPath: $dartSdkPath');
          print('stderr:\n${errorSink.toString()}');
          rethrow;
        }
        expect(errorSink.toString(), isEmpty);
        expect(outSink.toString(), contains('No issues found'));
        expect(exitCode, 0);
      } finally {
        Directory.current = origWorkingDir;
      }
    });
  }

  Future<void> test_fatalErrors() async {
    await drive('data/file_with_error.dart');
    expect(exitCode, 3);
  }

  Future<void> test_fatalHints() async {
    await drive('data/file_with_hint.dart', args: ['--fatal-hints']);
    expect(exitCode, 1);
  }

  Future<void> test_missingDartFile() async {
    await drive('data/NO_DART_FILE_HERE.dart');
    expect(exitCode, 3);
  }

  Future<void> test_missingOptionsFile() async {
    await drive('data/test_file.dart', options: 'data/NO_OPTIONS_HERE');
    expect(exitCode, 3);
  }

  Future<void> test_notFatalHints() async {
    await drive('data/file_with_hint.dart');
    expect(exitCode, 0);
  }

  Future<void> test_partFile() async {
    await driveMany([
      path.join(testDirectory, 'data/library_and_parts/lib.dart'),
      path.join(testDirectory, 'data/library_and_parts/part1.dart')
    ]);
    expect(exitCode, 0);
  }

  Future<void> test_partFile_dangling() async {
    await drive('data/library_and_parts/part2.dart');
    expect(exitCode, 3);
  }

  Future<void> test_partFile_extra() async {
    await driveMany([
      path.join(testDirectory, 'data/library_and_parts/lib.dart'),
      path.join(testDirectory, 'data/library_and_parts/part1.dart'),
      path.join(testDirectory, 'data/library_and_parts/part2.dart')
    ]);
    expect(exitCode, 3);
  }

  Future<void> test_partFile_reversed() async {
    var driver = Driver();
    await driver.start([
      path.join(testDirectory, 'data/library_and_parts/part1.dart'),
      path.join(testDirectory, 'data/library_and_parts/lib.dart')
    ]);
    expect(exitCode, 0);
  }
}

@reflectiveTest
class LinterTest extends BaseTest {
  String get analysisOptionsYaml => file_paths.analysisOptionsYaml;

  Future<void> test_containsLintRuleEntry() async {
    var options = _parseOptions('''
linter:
  rules:
    - foo
        ''');
    expect(containsLintRuleEntry(options), true);
    options = _parseOptions('''
        ''');
    expect(containsLintRuleEntry(options), false);
    options = _parseOptions('''
linter:
  rules:
    # - foo
        ''');
    expect(containsLintRuleEntry(options), true);
    options = _parseOptions('''
linter:
  # rules:
    # - foo
        ''');
    expect(containsLintRuleEntry(options), false);
  }

  Future<void> test_defaultLints_generatedLints() async {
    await _runLinter_defaultLints();
    expect(bulletToDash(outSink),
        contains('lint - Name types using UpperCamelCase'));
  }

  Future<void> test_defaultLints_getsDefaultLints() async {
    await _runLinter_defaultLints();

    /// Lints should be enabled.
    expect(analysisOptions.lint, isTrue);

    /// Default list should include camel_case_types.
    var lintNames = analysisOptions.lintRules.map((r) => r.name);
    expect(lintNames, contains('camel_case_types'));
  }

  Future<void> test_lintsInOptions_generatedLints() async {
    await _runLinter_lintsInOptions();
    expect(bulletToDash(outSink),
        contains('lint - Name types using UpperCamelCase'));
  }

  Future<void> test_lintsInOptions_getAnalysisOptions() async {
    await _runLinter_lintsInOptions();

    /// Lints should be enabled.
    expect(analysisOptions.lint, isTrue);

    /// The analysis options file specifies 'camel_case_types' and 'sort_pub_dependencies'.
    var lintNames = analysisOptions.lintRules.map((r) => r.name);
    expect(lintNames,
        orderedEquals(['camel_case_types', 'sort_pub_dependencies']));
  }

  Future<void> test_noLints_lintsDisabled() async {
    await _runLinter_noLintsFlag();
    expect(analysisOptions.lint, isFalse);
  }

  Future<void> test_noLints_noGeneratedWarnings() async {
    await _runLinter_noLintsFlag();
    expect(outSink.toString(), contains('No issues found'));
  }

  Future<void> test_noLints_noRegisteredLints() async {
    await _runLinter_noLintsFlag();
    expect(analysisOptions.lintRules, isEmpty);
  }

  Future<void> test_pubspec_lintsInOptions_generatedLints() async {
    await drive('data/linter_project/pubspec.yaml',
        options: 'data/linter_project/$analysisOptionsYaml');
    expect(bulletToDash(outSink), contains('lint - Sort pub dependencies'));
  }

  YamlMap _parseOptions(String src) =>
      AnalysisOptionsProvider().getOptionsFromString(src);

  Future<void> _runLinter_defaultLints() async {
    await drive('data/linter_project/test_file.dart',
        options: 'data/linter_project/$analysisOptionsYaml', args: ['--lints']);
  }

  Future<void> _runLinter_lintsInOptions() async {
    await drive('data/linter_project/test_file.dart',
        options: 'data/linter_project/$analysisOptionsYaml', args: ['--lints']);
  }

  Future<void> _runLinter_noLintsFlag() async {
    await drive('data/no_lints_project/test_file.dart',
        options: 'data/no_lints_project/$analysisOptionsYaml');
  }
}

@reflectiveTest
class NonDartFilesTest extends BaseTest {
  Future<void> test_analysisOptionsYaml() async {
    await withTempDirAsync((tempDir) async {
      var filePath = path.join(tempDir, file_paths.analysisOptionsYaml);
      File(filePath).writeAsStringSync('''
analyzer:
  string-mode: true
''');
      await drive(filePath);
      expect(
          bulletToDash(outSink),
          contains(
              "warning - The option 'string-mode' isn't supported by 'analyzer'"));
      expect(exitCode, 0);
    });
  }

  Future<void> test_manifestFileChecks() async {
    await withTempDirAsync((tempDir) async {
      var filePath = path.join(tempDir, file_paths.analysisOptionsYaml);
      File(filePath).writeAsStringSync('''
analyzer:
  optional-checks:
    chrome-os-manifest-checks: true
''');
      var manifestPath = path.join(tempDir, file_paths.androidManifestXml);
      File(manifestPath).writeAsStringSync('''
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
    <uses-feature android:name="android.software.home_screen" />
</manifest>
''');
      await drive(manifestPath, options: filePath);
      expect(
          bulletToDash(outSink),
          contains(
              "warning - The feature android.software.home_screen isn't supported on Chrome OS"));
      expect(exitCode, 0);
    });
  }

  Future<void> test_pubspecYaml() async {
    await withTempDirAsync((tempDir) async {
      var filePath = path.join(tempDir, file_paths.pubspecYaml);
      File(filePath).writeAsStringSync('''
name: foo
flutter:
  assets:
    doesNotExist.gif
''');
      await drive(filePath);
      expect(
          bulletToDash(outSink),
          contains(
              "warning - The value of the 'asset' field is expected to be a list of relative file paths"));
      expect(exitCode, 0);
    });
  }
}

@reflectiveTest
class OptionsTest extends BaseTest {
  String get analysisOptionsYaml => file_paths.analysisOptionsYaml;

  List<ErrorProcessor> get processors => analysisOptions.errorProcessors;

  ErrorProcessor processorFor(AnalysisError error) =>
      processors.firstWhere((p) => p.appliesTo(error));

  /// If a file is specified explicitly, it should be analyzed, even if
  /// it is excluded. Excludes work when an including directory is specified.
  Future<void> test_analysisOptions_excluded_requested() async {
    await drive(
      'data/exclude_test_project/lib/excluded_error.dart',
      options: 'data/exclude_test_project/$analysisOptionsYaml',
    );
    expect(
      bulletToDash(outSink),
      contains("error - Undefined class 'ExcludedUndefinedClass'"),
    );
    expect(outSink.toString(), contains('1 error found.'));
  }

  Future<void> test_analysisOptions_excludes() async {
    await drive('data/exclude_test_project',
        options: 'data/exclude_test_project/$analysisOptionsYaml');
    _expectUndefinedClassErrorsWithoutExclusions();
  }

  Future<void> test_analysisOptions_excludes_inner() async {
    await drive('data/exclude_portion_of_inner_context/inner',
        options: 'data/exclude_portion_of_inner_context/$analysisOptionsYaml');
    expect(
      bulletToDash(outSink),
      contains("error - Undefined class 'IncludedUndefinedClassInInner'"),
    );
    expect(outSink.toString(), contains('1 error found.'));
  }

  Future<void>
      test_analysisOptions_excludesRelativeToAnalysisOptions_explicit() async {
    // The exclude is relative to the project, not/ the analyzed path, and it
    // has to then understand that.
    await drive('data/exclude_test_project',
        options: 'data/exclude_test_project/$analysisOptionsYaml');
    _expectUndefinedClassErrorsWithoutExclusions();
  }

  Future<void> test_analyzeFilesInDifferentContexts() async {
    await driveMany([
      'data/linter_project/test_file.dart',
      'data/no_lints_project/test_file.dart',
    ], options: null);

    // Should have the lint in the project with lint rules enabled.
    expect(
        bulletToDash(outSink),
        contains(
            '${path.join('linter_project', 'test_file.dart')}:7:7 - camel_case_types'));
    // Should be just one lint in total.
    expect(outSink.toString(), contains('1 lint found.'));
  }

  Future<void> test_basic_filters() async {
    await _driveBasic();
    expect(processors, hasLength(3));

    // unused_local_variable: ignore
    var unused_local_variable =
        AnalysisError(TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
      ['x']
    ]);
    expect(processorFor(unused_local_variable).severity, isNull);

    // missing_return: error
    var missing_return =
        AnalysisError(TestSource(), 0, 1, HintCode.MISSING_RETURN, [
      ['x']
    ]);
    expect(processorFor(missing_return).severity, ErrorSeverity.ERROR);
    expect(bulletToDash(outSink),
        contains('error - The body might complete normally'));
    expect(outSink.toString(), contains('1 error and 1 warning found.'));
  }

  Future<void> test_includeDirective() async {
    var testDir = path.join(
        testDirectory, 'data', 'options_include_directive_tests_project');
    await drive(
      path.join(testDir, 'lib', 'test_file.dart'),
      args: [
        '--fatal-warnings',
        '--packages',
        path.join(testDir, '_packages'),
      ],
      options: path.join(testDir, 'analysis_options.yaml'),
    );
    expect(exitCode, 3);
    expect(outSink.toString(), contains('Unnecessary cast.'));
    expect(outSink.toString(), contains('isn\'t defined'));
    expect(outSink.toString(), contains('Avoid empty else statements'));
  }

  Future<void> test_multiple_inputs_two_directories() async {
    await driveMany([
      'data/multiple_inputs_two_directories/bin',
      'data/multiple_inputs_two_directories/lib',
    ]);
    expect(outSink.toString(), contains('2 errors found.'));
  }

  Future<void> test_multiple_inputs_two_files() async {
    await driveMany([
      'data/multiple_inputs_two_directories/bin/a.dart',
      'data/multiple_inputs_two_directories/lib/b.dart',
    ]);
    expect(outSink.toString(), contains('2 errors found.'));
  }

  Future<void> test_todo() async {
    await drive('data/file_with_todo.dart');
    expect(outSink.toString().contains('[info]'), isFalse);
  }

  Future<void> test_withFlags_overrideFatalWarning() async {
    await drive('data/options_tests_project/test_file.dart',
        args: ['--fatal-warnings'],
        options: 'data/options_tests_project/$analysisOptionsYaml');

    // missing_return: error
    var undefined_function = AnalysisError(
        TestSource(), 0, 1, CompileTimeErrorCode.UNDEFINED_FUNCTION, [
      ['x']
    ]);
    expect(processorFor(undefined_function).severity, ErrorSeverity.WARNING);
    // Should not be made fatal by `--fatal-warnings`.
    expect(bulletToDash(outSink),
        contains("warning - The function 'baz' isn't defined"));
    expect(outSink.toString(), contains('1 error and 1 warning found.'));
  }

  Future<void> _driveBasic() async {
    await drive('data/options_tests_project/test_file.dart',
        options: 'data/options_tests_project/$analysisOptionsYaml');
  }

  void _expectUndefinedClassErrorsWithoutExclusions() {
    expect(bulletToDash(outSink),
        contains("error - Undefined class 'IncludedUndefinedClass'"));
    expect(bulletToDash(outSink),
        isNot(contains("error - Undefined class 'ExcludedUndefinedClass'")));
    expect(outSink.toString(), contains('1 error found.'));
  }
}

class TestSource implements Source {
  TestSource();

  @override
  String get fullName => '/package/lib/test.dart';

  @override
  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
