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

library analyzer.test.source.analysis_options_provider_test;

import 'dart:core' hide Resource;

import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/analysis_options_provider.dart';
import 'package:unittest/unittest.dart';
import 'package:yaml/yaml.dart';

import '../reflective_tests.dart';
import '../resource_utils.dart';
import '../utils.dart';

main() {
  initializeTestEnvironment();
  runReflectiveTests(AnalysisOptionsProviderTest);
  group('AnalysisOptionsProvider', () {
    void expectMergesTo(String defaults, String overrides, String expected) {
      var optionsProvider = new AnalysisOptionsProvider();
      var defaultOptions = optionsProvider.getOptionsFromString(defaults);
      var overrideOptions = optionsProvider.getOptionsFromString(overrides);
      var merged = optionsProvider.merge(defaultOptions, overrideOptions);
      expect(merged, optionsProvider.getOptionsFromString(expected));
    }

    group('merging', () {
      test('integration', () {
        expectMergesTo(
            '''
analyzer:
  plugins:
    - p1
    - p2
  errors:
    unused_local_variable : error
linter:
  rules:
    - camel_case_types
    - one_member_abstracts
''',
            '''
analyzer:
  plugins:
    - p3
  errors:
    unused_local_variable : ignore # overrides error
linter:
  rules:
    one_member_abstracts: false # promotes and disables
    always_specify_return_types: true
''',
            '''
analyzer:
  plugins:
    - p1
    - p2
    - p3
  errors:
    unused_local_variable : ignore
linter:
  rules:
    camel_case_types: true
    one_member_abstracts: false
    always_specify_return_types: true
''');
      });
    });
  });

  group('AnalysisOptionsProvider', () {
    test('test_bad_yaml (1)', () {
      var src = '''
    analyzer: # <= bang
strong-mode: true
''';

      var optionsProvider = new AnalysisOptionsProvider();
      expect(() => optionsProvider.getOptionsFromString(src),
          throwsA(new isInstanceOf<OptionsFormatException>()));
    });

    test('test_bad_yaml (2)', () {
      var src = '''
analyzer:
  strong-mode:true # missing space (sdk/issues/24885)
''';

      var optionsProvider = new AnalysisOptionsProvider();
      // Should not throw an exception.
      var options = optionsProvider.getOptionsFromString(src);
      // Should return a non-null options list.
      expect(options, isNotNull);
    });
  });
}

@reflectiveTest
class AnalysisOptionsProviderTest {
  TestPathTranslator pathTranslator;
  ResourceProvider resourceProvider;

  AnalysisOptionsProvider provider = new AnalysisOptionsProvider();

  void setUp() {
    var rawProvider = new MemoryResourceProvider(isWindows: isWindows);
    resourceProvider = new TestResourceProvider(rawProvider);
    pathTranslator = new TestPathTranslator(rawProvider);
  }

  void test_getOptions_crawlUp_hasInFolder() {
    pathTranslator.newFolder('/foo/bar');
    pathTranslator.newFile(
        '/foo/.analysis_options',
        r'''
analyzer:
  ignore:
    - foo
''');
    pathTranslator.newFile(
        '/foo/bar/.analysis_options',
        r'''
analyzer:
  ignore:
    - bar
''');
    Map<String, YamlNode> options = _getOptions('/foo/bar', crawlUp: true);
    expect(options, hasLength(1));
    {
      YamlMap analyzer = options['analyzer'];
      expect(analyzer, isNotNull);
      expect(analyzer['ignore'], unorderedEquals(['bar']));
    }
  }

  void test_getOptions_crawlUp_hasInParent() {
    pathTranslator.newFolder('/foo/bar/baz');
    pathTranslator.newFile(
        '/foo/.analysis_options',
        r'''
analyzer:
  ignore:
    - foo
''');
    pathTranslator.newFile(
        '/foo/bar/.analysis_options',
        r'''
analyzer:
  ignore:
    - bar
''');
    Map<String, YamlNode> options = _getOptions('/foo/bar/baz', crawlUp: true);
    expect(options, hasLength(1));
    {
      YamlMap analyzer = options['analyzer'];
      expect(analyzer, isNotNull);
      expect(analyzer['ignore'], unorderedEquals(['bar']));
    }
  }

  void test_getOptions_doesNotExist() {
    pathTranslator.newFolder('/notFile');
    Map<String, YamlNode> options = _getOptions('/notFile');
    expect(options, isEmpty);
  }

  void test_getOptions_empty() {
    pathTranslator.newFile('/.analysis_options', r'''#empty''');
    Map<String, YamlNode> options = _getOptions('/');
    expect(options, isNotNull);
    expect(options, isEmpty);
  }

  void test_getOptions_invalid() {
    pathTranslator.newFile('/.analysis_options', r''':''');
    expect(() {
      _getOptions('/');
    }, throws);
  }

  void test_getOptions_simple() {
    pathTranslator.newFile(
        '/.analysis_options',
        r'''
analyzer:
  ignore:
    - ignoreme.dart
    - 'sdk_ext/**'
''');
    Map<String, YamlNode> options = _getOptions('/');
    expect(options, hasLength(1));
    {
      YamlMap analyzer = options['analyzer'];
      expect(analyzer, hasLength(1));
      {
        YamlList ignore = analyzer['ignore'];
        expect(ignore, hasLength(2));
        expect(ignore[0], 'ignoreme.dart');
        expect(ignore[1], 'sdk_ext/**');
      }
    }
  }

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