// Copyright (c) 2020, 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:args/command_runner.dart';

import '../io.dart';
import '../style_fix.dart';
import 'formatter_options.dart';
import 'options.dart';
import 'output.dart';
import 'show.dart';
import 'summary.dart';

class FormatCommand extends Command<int> {
  @override
  String get name => 'format';

  @override
  String get description => 'Idiomatically format Dart source code.';

  @override
  String get invocation =>
      '${runner!.executableName} $name [options...] <files or directories...>';

  FormatCommand({bool verbose = false}) {
    defineOptions(argParser, oldCli: false, verbose: verbose);
  }

  @override
  Future<int> run() async {
    var argResults = this.argResults!;

    if (argResults['version']) {
      print(dartStyleVersion);
      return 0;
    }

    var show = const {
      'all': Show.all,
      'changed': Show.changed,
      'none': Show.none
    }[argResults['show']]!;

    var output = const {
      'write': Output.write,
      'show': Output.show,
      'none': Output.none,
      'json': Output.json,
    }[argResults['output']]!;

    var summary = Summary.none;
    switch (argResults['summary'] as String) {
      case 'line':
        summary = Summary.line();
        break;
      case 'profile':
        summary = Summary.profile();
        break;
    }

    // If the user is sending code through stdin, default the output to stdout.
    if (!argResults.wasParsed('output') && argResults.rest.isEmpty) {
      output = Output.show;
    }

    // If the user wants to print the code and didn't indicate how the files
    // should be printed, default to only showing the code.
    if (!argResults.wasParsed('show') &&
        (output == Output.show || output == Output.json)) {
      show = Show.none;
    }

    // If the user wants JSON output, default to no summary.
    if (!argResults.wasParsed('summary') && output == Output.json) {
      summary = Summary.none;
    }

    // Can't use --verbose with anything but --help.
    if (argResults['verbose'] && !argResults['help']) {
      usageException('Can only use --verbose with --help.');
    }

    // Can't use any summary with JSON output.
    if (output == Output.json && summary != Summary.none) {
      usageException('Cannot print a summary with JSON output.');
    }

    int pageWidth;
    try {
      pageWidth = int.parse(argResults['line-length']);
    } on FormatException catch (_) {
      usageException('--line-length must be an integer, was '
          '"${argResults['line-length']}".');
    }

    int indent;
    try {
      indent = int.parse(argResults['indent']);
      if (indent < 0 || indent.toInt() != indent) throw FormatException();
    } on FormatException catch (_) {
      usageException('--indent must be a non-negative integer, was '
          '"${argResults['indent']}".');
    }

    var fixes = <StyleFix>[];
    if (argResults['fix']) fixes.addAll(StyleFix.all);
    for (var fix in StyleFix.all) {
      if (argResults['fix-${fix.name}']) {
        if (argResults['fix']) {
          usageException('--fix-${fix.name} is redundant with --fix.');
        }

        fixes.add(fix);
      }
    }

    List<int>? selection;
    try {
      selection = parseSelection(argResults, 'selection');
    } on FormatException catch (exception) {
      usageException(exception.message);
    }

    var followLinks = argResults['follow-links'];
    var setExitIfChanged = argResults['set-exit-if-changed'] as bool;

    // If stdin isn't connected to a pipe, then the user is not passing
    // anything to stdin, so let them know they made a mistake.
    if (argResults.rest.isEmpty && stdin.hasTerminal) {
      usageException('Missing paths to code to format.');
    }

    if (argResults.rest.isEmpty && output == Output.write) {
      usageException('Cannot use --output=write when reading from stdin.');
    }

    if (argResults.wasParsed('stdin-name') && argResults.rest.isNotEmpty) {
      usageException('Cannot pass --stdin-name when not reading from stdin.');
    }
    var stdinName = argResults['stdin-name'] as String;

    var options = FormatterOptions(
        indent: indent,
        pageWidth: pageWidth,
        followLinks: followLinks,
        fixes: fixes,
        show: show,
        output: output,
        summary: summary,
        setExitIfChanged: setExitIfChanged);

    if (argResults.rest.isEmpty) {
      await formatStdin(options, selection, stdinName);
    } else {
      formatPaths(options, argResults.rest);
      options.summary.show();
    }

    // Return the exitCode explicitly for tools which embed dart_style
    // and set their own exitCode.
    return exitCode;
  }
}
