// 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';

  StringSink _savedOutSink, _savedErrorSink;
  int _savedExitCode;
  ExitHandler _savedExitHandler;

  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 is not 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 - This function has a return type of 'int'"));
    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);
}
