// Copyright (c) 2018, 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 'package:dartfix/src/options.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';

import 'test_context.dart';

main() {
  TestContext context;
  TestLogger logger;

  setUp(() {
    context = new TestContext();
    logger = new TestLogger();
  });

  String p(String filePath) => context.convertPath(filePath);

  Options parse(
    List<String> args, {
    String errorOut,
    int exitCode,
    bool force = false,
    List<String> includeFixes = const <String>[],
    List<String> excludeFixes = const <String>[],
    bool showHelp = false,
    String normalOut,
    bool requiredFixes = false,
    bool overwrite = false,
    String serverSnapshot,
    List<String> targetSuffixes,
    bool verbose = false,
  }) {
    Options options;
    int actualExitCode;
    try {
      options = Options.parse(args, context, logger);
    } on TestExit catch (e) {
      actualExitCode = e.code;
    }
    expect(logger.stderrBuffer.toString(),
        errorOut != null ? contains(errorOut) : isEmpty);
    expect(logger.stdoutBuffer.toString(),
        normalOut != null ? contains(normalOut) : isEmpty);
    if (exitCode != null) {
      expect(actualExitCode, exitCode, reason: 'exit code');
      return null;
    } else {
      expect(actualExitCode, isNull, reason: 'exit code');
    }
    expect(options.force, force);
    expect(options.requiredFixes, requiredFixes);
    expect(options.overwrite, overwrite);
    expect(options.serverSnapshot, serverSnapshot);
    expect(options.showHelp, showHelp);
    expect(options.includeFixes, includeFixes);
    expect(options.excludeFixes, excludeFixes);
    expect(options.verbose, verbose);
    expect(path.isAbsolute(options.sdkPath), isTrue, reason: options.sdkPath);
    for (String target in options.targets) {
      expect(target, isNotNull);
      expect(path.isAbsolute(target), isTrue, reason: '$target');
    }
    if (targetSuffixes != null) {
      for (String suffix in targetSuffixes) {
        expectContains(options.targets, suffix);
      }
    }
    return options;
  }

  test('exclude fix', () {
    parse(['--exclude', 'c', '--exclude', 'd', 'foo'],
        excludeFixes: ['c', 'd'], targetSuffixes: ['foo']);
  });

  test('force', () {
    parse(['--force', 'foo'], force: true, targetSuffixes: ['foo']);
  });

  test('help explicit', () {
    parse(['--help'], normalOut: 'Display this help message', showHelp: true);
  });

  test('help implicit', () {
    parse([], normalOut: 'Display this help message', showHelp: true);
  });

  test('include fix', () {
    parse(['--include', 'a', '--include', 'b', 'foo'],
        includeFixes: ['a', 'b'], targetSuffixes: ['foo']);
  });

  test('invalid option', () {
    parse(['--foo'],
        errorOut: 'Could not find an option named "foo"', exitCode: 15);
  });

  test('invalid option no logger', () {
    try {
      Options.parse(['--foo'], context, null);
      fail('Expected exception');
    } on TestExit catch (e) {
      expect(e.code, 15, reason: 'exit code');
    }
  });

  test('invalid target', () {
    parse(['foo.dart'],
        errorOut: 'Expected directory, but found', exitCode: 15);
  });

  test('overwrite', () {
    parse(['--overwrite', 'foo'], overwrite: true, targetSuffixes: ['foo']);
  });

  test('required fixes', () {
    parse(['--required', 'foo'], requiredFixes: true);
  });

  test('server snapshot', () {
    parse(['--server', 'some/path', 'foo'], serverSnapshot: 'some/path');
  });

  test('simple', () {
    parse(['foo'], targetSuffixes: ['foo']);
  });

  test('two targets', () {
    parse([p('one/foo'), p('two/bar')],
        targetSuffixes: [p('one/foo'), p('two/bar')]);
  });

  test('verbose', () {
    parse(['--verbose', 'foo'], verbose: true);
  });
}

void expectOneFileTarget(Options options, String fileName) {
  expect(options.targets, hasLength(1));
  final target = options.targets[0];
  expect(target.endsWith(fileName), isTrue);
}

void expectContains(Iterable<String> collection, String suffix) {
  for (String elem in collection) {
    if (elem.endsWith(suffix)) {
      return;
    }
  }
  fail('Expected one of $collection\n  to end with "$suffix"');
}
