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

import 'package:args/command_runner.dart';

import 'build.dart';
import 'clean.dart';
import 'exceptions.dart';
import 'generate_fallback_font_data.dart';
import 'licenses.dart';
import 'run.dart';
import 'test_runner.dart';
import 'utils.dart';

CommandRunner<bool> runner = CommandRunner<bool>(
  'felt',
  'Command-line utility for building and testing Flutter web engine.',
)
  ..addCommand(BuildCommand())
  ..addCommand(CleanCommand())
  ..addCommand(GenerateFallbackFontDataCommand())
  ..addCommand(LicensesCommand())
  ..addCommand(RunCommand())
  ..addCommand(TestCommand());

Future<void> main(List<String> rawArgs) async {
  // Remove --clean from the list as that's processed by the wrapper script.
  final List<String> args = rawArgs.where((String arg) => arg != '--clean').toList();

  if (args.isEmpty) {
    // The felt tool was invoked with no arguments. Print usage.
    runner.printUsage();
    io.exit(64); // Exit code 64 indicates a usage error.
  }

  _listenToShutdownSignals();

  int exitCode = -1;
  try {
    final bool? result = await runner.run(args);
    if (result != true) {
      print('Sub-command failed: `${args.join(' ')}`');
      exitCode = 1;
    }
  } on UsageException catch (e) {
    print(e);
    exitCode = 64; // Exit code 64 indicates a usage error.
  } on ToolExit catch (exception) {
    io.stderr.writeln(exception.message);
    exitCode = exception.exitCode;
  } on ProcessException catch (e) {
    io.stderr.writeln('description: ${e.description}'
        'executable: ${e.executable} '
        'arguments: ${e.arguments} '
        'exit code: ${e.exitCode}');
    exitCode = e.exitCode ?? 1;
  } catch (e) {
    rethrow;
  } finally {
    await cleanup();
    // The exit code is changed by one of the branches.
    if (exitCode != -1) {
      io.exit(exitCode);
    }
  }

  // Sometimes the Dart VM refuses to quit.
  io.exit(io.exitCode);
}

void _listenToShutdownSignals() {
  io.ProcessSignal.sigint.watch().listen((_) async {
    print('Received SIGINT. Shutting down.');
    await cleanup();
    io.exit(1);
  });

  // SIGTERM signals are not generated under Windows.
  // See https://docs.microsoft.com/en-us/previous-versions/xdkz3x12(v%3Dvs.140)
  if (!io.Platform.isWindows) {
    io.ProcessSignal.sigterm.watch().listen((_) async {
      await cleanup();
      print('Received SIGTERM. Shutting down.');
      io.exit(1);
    });
  }
}
