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

import 'package:analyzer/src/util/sdk.dart';
import 'package:args/args.dart';
import 'package:meta/meta.dart';

@visibleForTesting
StringSink errorSink = stderr;

@visibleForTesting
StringSink outSink = stdout;

@visibleForTesting
Stream<List<int>> inputStream = stdin;

@visibleForTesting
ExitHandler exitHandler = exit;

@visibleForTesting
typedef void ExitHandler(int code);

/// Command line options for `dartfix`.
class Options {
  List<String> analysisRoots;
  bool dryRun;
  String sdkPath;
  bool verbose;

  static Options parse(List<String> args,
      {printAndFail(String msg) = printAndFail}) {
    final parser = new ArgParser(allowTrailingOptions: true);

    parser
      ..addOption(_sdkPathOption, help: 'The path to the Dart SDK.')
      ..addFlag(_dryRunOption,
          abbr: 'n',
          help: 'Calculate and display the recommended changes,'
              ' but exit before applying them',
          defaultsTo: false,
          negatable: false)
      ..addFlag(_helpOption,
          abbr: 'h',
          help:
              'Display this help message. Add --verbose to show hidden options.',
          defaultsTo: false,
          negatable: false)
      ..addFlag(_verboseOption,
          abbr: 'v',
          defaultsTo: false,
          help: 'Verbose output.',
          negatable: false);

    ArgResults results;
    try {
      results = parser.parse(args);
    } on FormatException catch (e) {
      errorSink.writeln(e.message);
      _showUsage(parser);
      exitHandler(15);
      return null; // Only reachable in testing.
    }

    if (results[_helpOption] as bool) {
      _showUsage(parser);
      exitHandler(0);
      return null; // Only reachable in testing.
    }

    Options options = new Options._fromArgs(results);

    // Check Dart SDK, and infer if unspecified.
    options.sdkPath ??= getSdkPath(args);
    String sdkPath = options.sdkPath;
    if (sdkPath == null) {
      errorSink.writeln('No Dart SDK found.');
      _showUsage(parser);
      return null; // Only reachable in testing.
    }
    if (!(new Directory(sdkPath)).existsSync()) {
      printAndFail('Invalid Dart SDK path: $sdkPath');
      return null; // Only reachable in testing.
    }

    // Check for files and/or directories to analyze.
    if (options.analysisRoots == null || options.analysisRoots.isEmpty) {
      errorSink.writeln('Expected at least one file or directory to analyze.');
      _showUsage(parser);
      exitHandler(15);
      return null; // Only reachable in testing.
    }

    return options;
  }

  Options._fromArgs(ArgResults results)
      : analysisRoots = results.rest,
        dryRun = results[_dryRunOption] as bool,
        sdkPath = results[_sdkPathOption] as String,
        verbose = results[_verboseOption] as bool;

  static _showUsage(ArgParser parser) {
    errorSink.writeln(
        'Usage: $_binaryName [options...] <directory or list of files>');
    errorSink.writeln('');
    errorSink.writeln(parser.usage);
  }
}

const _binaryName = 'dartfix';
const _dryRunOption = 'dry-run';
const _helpOption = 'help';
const _sdkPathOption = 'dart-sdk';
const _verboseOption = 'verbose';

/// Print the given [message] to stderr and exit with the given [exitCode].
void printAndFail(String message, {int exitCode: 15}) {
  errorSink.writeln(message);
  exitHandler(exitCode);
}
