// Copyright (c) 2016, 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/analyzer.dart';
import 'package:analyzer/src/command_line/arguments.dart';
import 'package:analyzer/src/summary/summary_sdk.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';

import '../../lib/src/analyzer/context.dart';
import '../../lib/src/analyzer/command.dart';
import '../../lib/src/analyzer/module_compiler.dart';
import '../testing.dart' show repoDirectory, testDirectory;

/// The `test/options` directory.
final optionsDir = path.join(testDirectory, 'options');

/// Summary file for testing.
final sdkSummaryFile = path.join(repoDirectory, 'gen', 'sdk', 'ddc_sdk.sum');

final sdkSummaryArgs = ['--$sdkSummaryPathOption', sdkSummaryFile];

main() {
  test('basic', () {
    var options = AnalyzerOptions.basic();
    var compiler = ModuleCompiler(options, analysisRoot: optionsDir);
    var processors = compiler.context.analysisOptions.errorProcessors;
    expect(processors, hasLength(1));
    expect(processors[0].code, CompileTimeErrorCode.UNDEFINED_CLASS.name);
  });

  test('basic sdk summary', () {
    expect(File(sdkSummaryFile).existsSync(), isTrue);
    var options = AnalyzerOptions.basic(dartSdkSummaryPath: sdkSummaryFile);
    var compiler = ModuleCompiler(options, analysisRoot: optionsDir);
    var context = compiler.context;
    var sdk = context.sourceFactory.dartSdk;
    expect(sdk, const TypeMatcher<SummaryBasedDartSdk>());
    var processors = context.analysisOptions.errorProcessors;
    expect(processors, hasLength(1));
    expect(processors[0].code, CompileTimeErrorCode.UNDEFINED_CLASS.name);
  });

  test('fromArgs', () {
    var args = <String>[];
    //TODO(danrubel) remove sdkSummaryArgs once all SDKs have summary file
    args.addAll(sdkSummaryArgs);
    var argResults = ddcArgParser().parse(args);
    var options = AnalyzerOptions.fromArguments(argResults);
    var compiler = ModuleCompiler(options, analysisRoot: optionsDir);
    var processors = compiler.context.analysisOptions.errorProcessors;
    expect(processors, hasLength(1));
    expect(processors[0].code, CompileTimeErrorCode.UNDEFINED_CLASS.name);
  });

  test('fromArgs options file 2', () {
    var optionsFile2 = path.join(optionsDir, 'analysis_options_2.yaml');
    expect(File(optionsFile2).existsSync(), isTrue);
    var args = <String>['--$analysisOptionsFileOption', optionsFile2];
    //TODO(danrubel) remove sdkSummaryArgs once all SDKs have summary file
    args.addAll(sdkSummaryArgs);
    var argResults = ddcArgParser().parse(args);
    var options = AnalyzerOptions.fromArguments(argResults);
    var compiler = ModuleCompiler(options, analysisRoot: optionsDir);
    var processors = compiler.context.analysisOptions.errorProcessors;
    expect(processors, hasLength(1));
    expect(processors[0].code, CompileTimeErrorCode.DUPLICATE_DEFINITION.name);
  });

  test('custom module name for summary', () {
    var args = <String>[
      '-snormal',
      '-scustom/path=module',
      '-sanother',
      '--summary=custom/path2=module2'
    ];

    var argResults = ddcArgParser().parse(args);
    var options = CompilerOptions.fromArguments(argResults);
    expect(options.summaryModules.keys.toList(),
        orderedEquals(['normal', 'custom/path', 'another', 'custom/path2']));
    expect(options.summaryModules['custom/path'], equals('module'));
    expect(options.summaryModules['custom/path2'], equals('module2'));
    expect(options.summaryModules.containsKey('normal'), isFalse);
  });
}
