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

import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/analysis_options/error/option_codes.dart';
import 'package:analyzer/src/dart/error/hint_codes.dart';
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/lint/registry.dart';
import 'package:analyzer/src/manifest/manifest_warning_code.dart';
import 'package:analyzer/src/task/options.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:yaml/yaml.dart';

import '../../generated/test_support.dart';
import '../../resource_utils.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(ContextConfigurationTest);
    defineReflectiveTests(ErrorCodeValuesTest);
    defineReflectiveTests(GenerateOldOptionsErrorsTaskTest);
    defineReflectiveTests(OptionsFileValidatorTest);
    defineReflectiveTests(OptionsProviderTest);
  });
}

@reflectiveTest
class ContextConfigurationTest {
  final AnalysisOptions analysisOptions = AnalysisOptionsImpl();

  final AnalysisOptionsProvider optionsProvider = AnalysisOptionsProvider();

  void configureContext(String optionsSource) =>
      applyToAnalysisOptions(analysisOptions, parseOptions(optionsSource));

  YamlMap parseOptions(String source) =>
      optionsProvider.getOptionsFromString(source);

  test_configure_error_processors() {
    configureContext('''
analyzer:
  errors:
    invalid_assignment: ignore
    unused_local_variable: error
''');

    List<ErrorProcessor> processors = analysisOptions.errorProcessors;
    expect(processors, hasLength(2));

    var unused_local = new AnalysisError(
        new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
      ['x']
    ]);
    var invalid_assignment = new AnalysisError(
        new TestSource(), 0, 1, StaticTypeWarningCode.INVALID_ASSIGNMENT, [
      ['x'],
      ['y']
    ]);

    // ignore
    var invalidAssignment =
        processors.firstWhere((p) => p.appliesTo(invalid_assignment));
    expect(invalidAssignment.severity, isNull);

    // error
    var unusedLocal = processors.firstWhere((p) => p.appliesTo(unused_local));
    expect(unusedLocal.severity, ErrorSeverity.ERROR);
  }

  test_configure_excludes() {
    configureContext('''
analyzer:
  exclude:
    - foo/bar.dart
    - 'test/**'
''');

    List<String> excludes = analysisOptions.excludePatterns;
    expect(excludes, unorderedEquals(['foo/bar.dart', 'test/**']));
  }

  test_configure_plugins_list() {
    configureContext('''
analyzer:
  plugins:
    - angular2
    - intl
''');

    List<String> names = analysisOptions.enabledPluginNames;
    expect(names, ['angular2', 'intl']);
  }

  test_configure_plugins_map() {
    configureContext('''
analyzer:
  plugins:
    angular2:
      enabled: true
''');

    List<String> names = analysisOptions.enabledPluginNames;
    expect(names, ['angular2']);
  }

  test_configure_plugins_string() {
    configureContext('''
analyzer:
  plugins:
    angular2
''');

    List<String> names = analysisOptions.enabledPluginNames;
    expect(names, ['angular2']);
  }

  test_configure_chromeos_checks() {
    configureContext('''
analyzer:
  optional-checks:
    chrome-os-manifest-checks
''');
    expect(true, analysisOptions.chromeOsManifestChecks);
  }

  test_configure_chromeos_checks_map() {
    configureContext('''
analyzer:
  optional-checks:
    chrome-os-manifest-checks : true
''');
    expect(true, analysisOptions.chromeOsManifestChecks);
  }
}

@reflectiveTest
class ErrorCodeValuesTest {
  test_errorCodes() {
    var errorTypeMap = <Type, List<ErrorCode>>{};
    for (ErrorCode code in errorCodeValues) {
      errorTypeMap.putIfAbsent(code.runtimeType, () => <ErrorCode>[]).add(code);
    }

    int missingErrorCodeCount = 0;
    errorTypeMap.forEach((Type errorType, List<ErrorCode> codes) {
      var listedNames = codes.map((ErrorCode code) => code.name).toSet();

      var declaredNames = reflectClass(errorType)
          .declarations
          .values
          .map((DeclarationMirror declarationMirror) {
        String name = declarationMirror.simpleName.toString();
        //TODO(danrubel): find a better way to extract the text from the symbol
        assert(name.startsWith('Symbol("') && name.endsWith('")'));
        return name.substring(8, name.length - 2);
      }).where((String name) {
        return name == name.toUpperCase();
      }).toList();

      // Remove declared names that are not supposed to be in errorCodeValues

      if (errorType == AnalysisOptionsErrorCode) {
        declaredNames
            .remove(AnalysisOptionsErrorCode.INCLUDED_FILE_PARSE_ERROR.name);
      } else if (errorType == AnalysisOptionsWarningCode) {
        declaredNames
            .remove(AnalysisOptionsWarningCode.INCLUDE_FILE_NOT_FOUND.name);
        declaredNames
            .remove(AnalysisOptionsWarningCode.INCLUDED_FILE_WARNING.name);
        declaredNames
            .remove(AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT.name);
      } else if (errorType == StaticWarningCode) {
        declaredNames.remove(
            StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS.name +
                '_PLUS');
      } else if (errorType == StrongModeCode) {
        void removeCode(StrongModeCode code) {
          String name = code.name;
          declaredNames.remove(name);
          if (name.startsWith('STRONG_MODE_')) {
            declaredNames.remove(name.substring(12));
          }
        }

        removeCode(StrongModeCode.DOWN_CAST_COMPOSITE);
        removeCode(StrongModeCode.DOWN_CAST_IMPLICIT);
        removeCode(StrongModeCode.DOWN_CAST_IMPLICIT_ASSIGN);
        removeCode(StrongModeCode.DYNAMIC_CAST);
        removeCode(StrongModeCode.ASSIGNMENT_CAST);
        removeCode(StrongModeCode.INVALID_PARAMETER_DECLARATION);
        removeCode(StrongModeCode.COULD_NOT_INFER);
        removeCode(StrongModeCode.INFERRED_TYPE);
        removeCode(StrongModeCode.INFERRED_TYPE_LITERAL);
        removeCode(StrongModeCode.INFERRED_TYPE_ALLOCATION);
        removeCode(StrongModeCode.INFERRED_TYPE_CLOSURE);
        removeCode(StrongModeCode.INVALID_CAST_LITERAL);
        removeCode(StrongModeCode.INVALID_CAST_LITERAL_LIST);
        removeCode(StrongModeCode.INVALID_CAST_LITERAL_MAP);
        removeCode(StrongModeCode.INVALID_CAST_LITERAL_SET);
        removeCode(StrongModeCode.INVALID_CAST_FUNCTION_EXPR);
        removeCode(StrongModeCode.INVALID_CAST_NEW_EXPR);
        removeCode(StrongModeCode.INVALID_CAST_METHOD);
        removeCode(StrongModeCode.INVALID_CAST_FUNCTION);
        removeCode(StrongModeCode.INVALID_SUPER_INVOCATION);
        removeCode(StrongModeCode.NON_GROUND_TYPE_CHECK_INFO);
        removeCode(StrongModeCode.DYNAMIC_INVOKE);
        removeCode(StrongModeCode.IMPLICIT_DYNAMIC_PARAMETER);
        removeCode(StrongModeCode.IMPLICIT_DYNAMIC_RETURN);
        removeCode(StrongModeCode.IMPLICIT_DYNAMIC_VARIABLE);
        removeCode(StrongModeCode.IMPLICIT_DYNAMIC_FIELD);
        removeCode(StrongModeCode.IMPLICIT_DYNAMIC_TYPE);
        removeCode(StrongModeCode.IMPLICIT_DYNAMIC_LIST_LITERAL);
        removeCode(StrongModeCode.IMPLICIT_DYNAMIC_MAP_LITERAL);
        removeCode(StrongModeCode.IMPLICIT_DYNAMIC_FUNCTION);
        removeCode(StrongModeCode.IMPLICIT_DYNAMIC_METHOD);
        removeCode(StrongModeCode.IMPLICIT_DYNAMIC_INVOKE);
        removeCode(StrongModeCode.NOT_INSTANTIATED_BOUND);
        removeCode(StrongModeCode.TOP_LEVEL_CYCLE);
        removeCode(StrongModeCode.TOP_LEVEL_FUNCTION_LITERAL_BLOCK);
        removeCode(StrongModeCode.TOP_LEVEL_IDENTIFIER_NO_TYPE);
        removeCode(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER);
        removeCode(StrongModeCode.TOP_LEVEL_INSTANCE_METHOD);
      } else if (errorType == TodoCode) {
        declaredNames.remove('TODO_REGEX');
      } else if (errorType == ParserErrorCode) {
        declaredNames.remove('CONST_AFTER_FACTORY');
      } else if (errorType == ManifestWarningCode) {
        declaredNames.remove('NON_RESIZABLE_ACTIVITY');
        declaredNames.remove('SETTING_ORIENTATION_ON_ACTIVITY');
      }

      // Assert that all remaining declared names are in errorCodeValues

      for (String declaredName in declaredNames) {
        if (!listedNames.contains(declaredName)) {
          ++missingErrorCodeCount;
          print('   errorCodeValues is missing $errorType $declaredName');
        }
      }
    });
    expect(missingErrorCodeCount, 0, reason: 'missing error code names');

    // Apparently, duplicate error codes are allowed
    //    expect(
    //      ErrorFilterOptionValidator.errorCodes.length,
    //      errorCodeValues.length,
    //      reason: 'some errorCodeValues have the same name',
    //    );
  }
}

class ErrorProcessorMatcher extends Matcher {
  final ErrorProcessor required;

  ErrorProcessorMatcher(this.required);

  @override
  Description describe(Description desc) => desc
    ..add("an ErrorProcessor setting ${required.code} to ${required.severity}");

  @override
  bool matches(dynamic o, Map<dynamic, dynamic> options) {
    return o is ErrorProcessor &&
        o.code.toUpperCase() == required.code.toUpperCase() &&
        o.severity == required.severity;
  }
}

@reflectiveTest
class GenerateOldOptionsErrorsTaskTest with ResourceProviderMixin {
  final AnalysisOptionsProvider optionsProvider = new AnalysisOptionsProvider();

  String get optionsFilePath => '/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}';

  test_does_analyze_old_options_files() {
    validate('''
analyzer:
  strong-mode: true
    ''', [
      AnalysisOptionsHintCode.DEPRECATED_ANALYSIS_OPTIONS_FILE_NAME,
      AnalysisOptionsHintCode.STRONG_MODE_SETTING_DEPRECATED
    ]);
  }

  test_finds_issues_in_old_options_files() {
    validate('''
analyzer:
  strong_mode: true
    ''', [
      AnalysisOptionsHintCode.DEPRECATED_ANALYSIS_OPTIONS_FILE_NAME,
      AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES
    ]);
  }

  void validate(String content, List<ErrorCode> expected) {
    final source = newFile(optionsFilePath, content: content).createSource();
    var options = optionsProvider.getOptionsFromSource(source);
    final OptionsFileValidator validator = new OptionsFileValidator(source);
    var errors = validator.validate(options);
    expect(errors.map((AnalysisError e) => e.errorCode),
        unorderedEquals(expected));
  }
}

@reflectiveTest
class OptionsFileValidatorTest {
  final OptionsFileValidator validator =
      new OptionsFileValidator(new TestSource());
  final AnalysisOptionsProvider optionsProvider = new AnalysisOptionsProvider();

  test_analyzer_enableExperiment_badValue() {
    validate('''
analyzer:
  enable-experiment:
    - not-an-experiment
    ''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITHOUT_VALUES]);
  }

  test_analyzer_enableExperiment_notAList() {
    validate('''
analyzer:
  enable-experiment:
    experiment: true
    ''', [AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT]);
  }

  test_analyzer_error_code_supported() {
    validate('''
analyzer:
  errors:
    unused_local_variable: ignore
    invalid_assignment: warning
    missing_return: error
    dead_code: info
''', []);
  }

  test_analyzer_error_code_supported_bad_value() {
    validate('''
analyzer:
  errors:
    unused_local_variable: ftw
    ''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES]);
  }

  test_analyzer_error_code_unsupported() {
    validate('''
analyzer:
  errors:
    not_supported: ignore
    ''', [AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE]);
  }

  test_analyzer_language_bad_format_list() {
    validate('''
analyzer:
  language:
    - enableSuperMixins: true
''', [AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT]);
  }

  test_analyzer_language_bad_format_scalar() {
    validate('''
analyzer:
  language: true
''', [AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT]);
  }

  test_analyzer_language_supports_empty() {
    validate('''
analyzer:
  language:
''', []);
  }

  test_analyzer_language_unsupported_key() {
    validate('''
analyzer:
  language:
    unsupported: true
''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES]);
  }

  test_analyzer_lint_codes_recognized() {
    Registry.ruleRegistry.register(new TestRule());
    validate('''
analyzer:
  errors:
    fantastic_test_rule: ignore
    ''', []);
  }

  test_analyzer_strong_mode_deprecated() {
    validate('''
analyzer:
  strong-mode: true
    ''', [AnalysisOptionsHintCode.STRONG_MODE_SETTING_DEPRECATED]);
  }

  test_analyzer_strong_mode_deprecated_key() {
    validate('''
analyzer:
  strong-mode:
    declaration-casts: false
''', [AnalysisOptionsWarningCode.ANALYSIS_OPTION_DEPRECATED]);
  }

  test_analyzer_strong_mode_error_code_supported() {
    validate('''
analyzer:
  errors:
    strong_mode_assignment_cast: ignore
''', []);
  }

  test_analyzer_strong_mode_false_removed() {
    validate('''
analyzer:
  strong-mode: false
    ''', [AnalysisOptionsWarningCode.SPEC_MODE_REMOVED]);
  }

  test_analyzer_strong_mode_unsupported_key() {
    validate('''
analyzer:
  strong-mode:
    unsupported: true
''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES]);
  }

  test_analyzer_strong_mode_unsupported_value() {
    validate('''
analyzer:
  strong-mode:
    implicit-dynamic: foo
''', [AnalysisOptionsWarningCode.UNSUPPORTED_VALUE]);
  }

  test_analyzer_supported_exclude() {
    validate('''
analyzer:
  exclude:
    - test/_data/p4/lib/lib1.dart
    ''', []);
  }

  test_analyzer_supported_strong_mode_supported_bad_value() {
    validate('''
analyzer:
  strong-mode: w00t
    ''', [AnalysisOptionsWarningCode.UNSUPPORTED_VALUE]);
  }

  test_analyzer_unsupported_option() {
    validate('''
analyzer:
  not_supported: true
    ''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES]);
  }

  test_linter_supported_rules() {
    Registry.ruleRegistry.register(new TestRule());
    validate('''
linter:
  rules:
    - fantastic_test_rule
    ''', []);
  }

  test_linter_unsupported_option() {
    validate('''
linter:
  unsupported: true
    ''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE]);
  }

  test_chromeos_manifest_checks() {
    validate('''
analyzer:
  optional-checks:
    chrome-os-manifest-checks
''', []);
  }

  test_chromeos_manifest_checks_invalid() {
    validate('''
analyzer:
  optional-checks:
    chromeos-manifest
''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE]);
  }

  void validate(String source, List<ErrorCode> expected) {
    var options = optionsProvider.getOptionsFromString(source);
    var errors = validator.validate(options);
    expect(errors.map((AnalysisError e) => e.errorCode),
        unorderedEquals(expected));
  }
}

@reflectiveTest
class OptionsProviderTest {
  TestPathTranslator pathTranslator;
  ResourceProvider resourceProvider;

  AnalysisOptionsProvider provider;

  String get optionsFilePath => '/analysis_options.yaml';

  void setUp() {
    var rawProvider = new MemoryResourceProvider();
    resourceProvider = new TestResourceProvider(rawProvider);
    pathTranslator = new TestPathTranslator(rawProvider);
    provider = new AnalysisOptionsProvider(new SourceFactory([
      new ResourceUriResolver(rawProvider),
    ]));
  }

  test_perform_include_merge() {
    pathTranslator.newFile('/other_options.yaml', '''
analyzer:
  exclude:
    - toplevelexclude.dart
  plugins:
    toplevelplugin:
      enabled: true
  errors:
    toplevelerror: warning
linter:
  rules:
    - toplevellint
''');
    String code = r'''
include: other_options.yaml
analyzer:
  exclude:
    - lowlevelexclude.dart
  plugins:
    lowlevelplugin:
      enabled: true
  errors:
    lowlevelerror: warning
linter:
  rules:
    - lowlevellint
''';
    pathTranslator.newFile(optionsFilePath, code);

    final lowlevellint = new TestRule.withName('lowlevellint');
    final toplevellint = new TestRule.withName('toplevellint');
    Registry.ruleRegistry.register(lowlevellint);
    Registry.ruleRegistry.register(toplevellint);
    final options = _getOptionsObject('/');

    expect(options.lintRules, unorderedEquals([toplevellint, lowlevellint]));
    expect(options.enabledPluginNames,
        unorderedEquals(['toplevelplugin', 'lowlevelplugin']));
    expect(options.excludePatterns,
        unorderedEquals(['toplevelexclude.dart', 'lowlevelexclude.dart']));
    expect(
        options.errorProcessors,
        unorderedMatches([
          new ErrorProcessorMatcher(
              new ErrorProcessor('toplevelerror', ErrorSeverity.WARNING)),
          new ErrorProcessorMatcher(
              new ErrorProcessor('lowlevelerror', ErrorSeverity.WARNING))
        ]));
  }

  YamlMap _getOptions(String posixPath, {bool crawlUp: false}) {
    Resource resource = pathTranslator.getResource(posixPath);
    return provider.getOptions(resource, crawlUp: crawlUp);
  }

  AnalysisOptions _getOptionsObject(String posixPath, {bool crawlUp: false}) {
    final map = _getOptions(posixPath, crawlUp: crawlUp);
    final options = new AnalysisOptionsImpl();
    applyToAnalysisOptions(options, map);
    return options;
  }
}

class TestRule extends LintRule {
  TestRule() : super(name: 'fantastic_test_rule');

  TestRule.withName(String name) : super(name: name);
}
