// Copyright 2013 The Flutter Authors. 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:async';
import 'dart:convert';
import 'dart:io' as io;

import 'package:path/path.dart' as p;

import '../logger.dart';
import 'command.dart';
import 'flags.dart';

/// The 'format' command.
///
/// The format command implementation below works by spawning another Dart VM to
/// run the program under ci/bin/format.dart.
///
// TODO(team-engine): Part of https://github.com/flutter/flutter/issues/132807.
// Instead, format.dart should be moved under the engine_tool package and
// invoked by a function call. The file ci/bin/format.dart should be split up so
// that each of its `FormatCheckers` is in a separate file under src/formatters,
// and they should be unit-tested.
final class FormatCommand extends CommandBase {
  // ignore: public_member_api_docs
  FormatCommand({
    required super.environment,
  }) {
    argParser
      ..addFlag(
        allFlag,
        abbr: 'a',
        help: 'By default only dirty files are checked. This flag causes all '
              'files to be checked. (Slow)',
        negatable: false,
      )
      ..addFlag(
        dryRunFlag,
        abbr: 'd',
        help: 'Do not fix formatting in-place. Instead, print file diffs to '
              'the logs.',
        negatable: false,
      )
      ..addFlag(
        quietFlag,
        abbr: 'q',
        help: 'Silences all log messages except for errors and warnings',
        negatable: false,
      )
      ..addFlag(
        verboseFlag,
        abbr: 'v',
        help: 'Prints verbose output',
        negatable: false,
      );
  }

  @override
  String get name => 'format';

  @override
  String get description => 'Formats files using standard formatters and styles.';

  @override
  Future<int> run() async {
    final bool all = argResults![allFlag]! as bool;
    final bool dryRun = argResults![dryRunFlag]! as bool;
    final bool quiet = argResults![quietFlag]! as bool;
    final bool verbose = argResults![verboseFlag]! as bool;
    final String formatPath = p.join(
      environment.engine.flutterDir.path, 'ci', 'bin', 'format.dart',
    );

    final io.Process process = await environment.processRunner.processManager.start(
      <String>[
        environment.platform.resolvedExecutable,
        formatPath,
        if (all) '--all-files',
        if (!dryRun) '--fix',
        if (verbose) '--verbose',
      ],
      workingDirectory: environment.engine.flutterDir.path,
    );
    final Completer<void> stdoutComplete = Completer<void>();
    final Completer<void> stderrComplete = Completer<void>();

    final _FormatStreamer streamer = _FormatStreamer(
      environment.logger,
      dryRun,
      quiet,
    );
    process.stdout
      .transform<String>(const Utf8Decoder())
      .transform(const LineSplitter())
      .listen(
        streamer.nextStdout,
        onDone: () async => stdoutComplete.complete(),
      );
    process.stderr
      .transform<String>(const Utf8Decoder())
      .transform(const LineSplitter())
      .listen(
        streamer.nextStderr,
        onDone: () async => stderrComplete.complete(),
      );

    await Future.wait<void>(<Future<void>>[
      stdoutComplete.future, stderrComplete.future,
    ]);
    final int exitCode = await process.exitCode;

    return exitCode;
  }
}

class _FormatStreamer {
  _FormatStreamer(this.logger, this.dryRun, this.quiet);

  final Logger logger;
  final bool dryRun;
  final bool quiet;

  bool inADiff = false;
  bool inProgress = false;

  void nextStdout(String line) {
    if (quiet) {
      return;
    }
    final String l = line.trim();
    if (l == 'To fix, run `et format` or:') {
      inADiff = true;
    }
    if (l.isNotEmpty && (!inADiff || dryRun)) {
      if (_isProgressLine(l)) {
        inProgress = true;
        logger.clearLine();
        logger.status('$l\r', newline: false);
      } else {
        if (inProgress) {
          logger.clearLine();
          inProgress = false;
        }
        logger.status(l);
      }
    }
    if (l == 'DONE') {
      inADiff = false;
    }
  }

  void nextStderr(String line) {
    final String l = line.trim();
    if (l.isEmpty) {
      return;
    }
    logger.error(l);
  }

  bool _isProgressLine(String l) {
    final List<String> words = l.split(',');
    return words.isNotEmpty && words[0].endsWith('% done');
  }
}
