// Copyright 2014 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 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/process.dart';
import 'package:flutter_tools/src/base/terminal.dart';

import '../../src/common.dart';
import '../../src/fake_process_manager.dart';
import '../../src/fakes.dart';

void main() {
  group('process exceptions', () {
    late FakeProcessManager fakeProcessManager;
    late ProcessUtils processUtils;

    setUp(() {
      fakeProcessManager = FakeProcessManager.empty();
      processUtils = ProcessUtils(
        processManager: fakeProcessManager,
        logger: BufferLogger.test(),
      );
    });

    testWithoutContext('runAsync throwOnError: exceptions should be ProcessException objects', () async {
      fakeProcessManager.addCommand(const FakeCommand(
        command: <String>[
          'false',
        ],
        exitCode: 1,
      ));

      expect(() async => processUtils.run(<String>['false'], throwOnError: true), throwsProcessException());
    });
  });

  group('shutdownHooks', () {
    testWithoutContext('runInExpectedOrder', () async {
      int i = 1;
      int? cleanup;

      final ShutdownHooks shutdownHooks = ShutdownHooks(logger: BufferLogger.test());

      shutdownHooks.addShutdownHook(() async {
        cleanup = i++;
      });

      await shutdownHooks.runShutdownHooks();

      expect(cleanup, 1);
    });
  });

  group('output formatting', () {
    late FakeProcessManager processManager;
    late ProcessUtils processUtils;
    late BufferLogger logger;

    setUp(() {
      processManager = FakeProcessManager.empty();
      logger = BufferLogger.test();
      processUtils = ProcessUtils(
        processManager: processManager,
        logger: logger,
      );
    });

    testWithoutContext('Command output is not wrapped.', () async {
      final List<String> testString = <String>['0123456789' * 10];
      processManager.addCommand(FakeCommand(
        command: const <String>['command'],
        stdout: testString.join(),
        stderr: testString.join(),
      ));

      await processUtils.stream(<String>['command']);

      expect(logger.statusText, equals('${testString[0]}\n'));
      expect(logger.errorText, equals('${testString[0]}\n'));
    });

    testWithoutContext('Command output is filtered by mapFunction', () async {
      processManager.addCommand(const FakeCommand(
        command: <String>['command'],
        stdout: 'match\nno match',
        stderr: 'match\nno match',
      ));

      await processUtils.stream(<String>['command'], mapFunction: (String line) {
        if (line == 'match') {
          return line;
        }
        return null;
      });

      expect(logger.statusText, equals('match\n'));
      expect(logger.errorText, equals('match\n'));
    });
  });

  group('run', () {
    late FakeProcessManager fakeProcessManager;
    late ProcessUtils processUtils;

    setUp(() {
      fakeProcessManager = FakeProcessManager.empty();
      processUtils = ProcessUtils(
        processManager: fakeProcessManager,
        logger: BufferLogger.test(),
      );
    });

    testWithoutContext(' succeeds on success', () async {
      fakeProcessManager.addCommand(const FakeCommand(
        command: <String>[
          'whoohoo',
        ],
      ));
      expect((await processUtils.run(<String>['whoohoo'])).exitCode, 0);
    });

    testWithoutContext(' fails on failure', () async {
      fakeProcessManager.addCommand(const FakeCommand(
        command: <String>[
          'boohoo',
        ],
        exitCode: 1,
      ));
      expect((await processUtils.run(<String>['boohoo'])).exitCode, 1);
    });

    testWithoutContext(' throws on failure with throwOnError', () async {
      fakeProcessManager.addCommand(const FakeCommand(
        command: <String>[
          'kaboom',
        ],
        exitCode: 1,
      ));
      expect(() => processUtils.run(<String>['kaboom'], throwOnError: true), throwsProcessException());
    });

    testWithoutContext(' does not throw on allowed Failures', () async {
      fakeProcessManager.addCommand(const FakeCommand(
        command: <String>[
          'kaboom',
        ],
        exitCode: 1,
      ));
      expect(
        (await processUtils.run(
          <String>['kaboom'],
          throwOnError: true,
          allowedFailures: (int c) => c == 1,
        )).exitCode,
        1,
      );
    });

    testWithoutContext(' throws on disallowed failure', () async {
      fakeProcessManager.addCommand(const FakeCommand(
        command: <String>[
          'kaboom',
        ],
        exitCode: 2,
      ));
      expect(
        () => processUtils.run(
          <String>['kaboom'],
          throwOnError: true,
          allowedFailures: (int c) => c == 1,
        ),
        throwsProcessException(),
      );
    });
  });

  group('runSync', () {
    late FakeProcessManager fakeProcessManager;
    late ProcessUtils processUtils;
    late BufferLogger testLogger;

    setUp(() {
      fakeProcessManager = FakeProcessManager.empty();
      testLogger = BufferLogger(
        terminal: AnsiTerminal(
          stdio: FakeStdio(),
          platform: FakePlatform(),
        ),
        outputPreferences: OutputPreferences(wrapText: true, wrapColumn: 40),
      );
      processUtils = ProcessUtils(
        processManager: fakeProcessManager,
        logger: testLogger,
      );
    });

    testWithoutContext(' succeeds on success', () async {
      fakeProcessManager.addCommand(const FakeCommand(
        command: <String>[
          'whoohoo',
        ],
      ));
      expect(processUtils.runSync(<String>['whoohoo']).exitCode, 0);
    });

    testWithoutContext(' fails on failure', () async {
      fakeProcessManager.addCommand(const FakeCommand(
        command: <String>[
          'boohoo',
        ],
        exitCode: 1,
      ));
      expect(processUtils.runSync(<String>['boohoo']).exitCode, 1);
    });

    testWithoutContext('throws on failure with throwOnError', () async {
      const String stderr = 'Something went wrong.';
      fakeProcessManager.addCommand(const FakeCommand(
        command: <String>[
          'kaboom',
        ],
        exitCode: 1,
        stderr: stderr,
      ));
      expect(
        () => processUtils.runSync(<String>['kaboom'], throwOnError: true),
        throwsA(isA<ProcessException>().having(
          (ProcessException error) => error.message,
          'message',
          isNot(contains(stderr)),
        )),
      );
    });

    testWithoutContext('throws with stderr in exception on failure with verboseExceptions', () async {
      const String stderr = 'Something went wrong.';
      fakeProcessManager.addCommand(const FakeCommand(
        command: <String>[
          'verybad',
        ],
        exitCode: 1,
        stderr: stderr,
      ));
      expect(
        () => processUtils.runSync(
          <String>['verybad'],
          throwOnError: true,
          verboseExceptions: true,
        ),
        throwsProcessException(message: stderr),
      );
    });

    testWithoutContext(' does not throw on allowed Failures', () async {
      fakeProcessManager.addCommand(const FakeCommand(
        command: <String>[
          'kaboom',
        ],
        exitCode: 1,
      ));
      expect(
        processUtils.runSync(
          <String>['kaboom'],
          throwOnError: true,
          allowedFailures: (int c) => c == 1,
        ).exitCode,
        1);
    });

    testWithoutContext(' throws on disallowed failure', () async {
      fakeProcessManager.addCommand(const FakeCommand(
        command: <String>[
          'kaboom',
        ],
        exitCode: 2,
      ));
      expect(
        () => processUtils.runSync(
          <String>['kaboom'],
          throwOnError: true,
          allowedFailures: (int c) => c == 1,
        ),
        throwsProcessException(),
      );
    });

    testWithoutContext(' prints stdout and stderr to trace on success', () async {
      fakeProcessManager.addCommand(const FakeCommand(
        command: <String>[
          'whoohoo',
        ],
        stdout: 'stdout',
        stderr: 'stderr',
      ));
      expect(processUtils.runSync(<String>['whoohoo']).exitCode, 0);
      expect(testLogger.traceText, contains('stdout'));
      expect(testLogger.traceText, contains('stderr'));
    });

    testWithoutContext(' prints stdout to status and stderr to error on failure with throwOnError', () async {
      fakeProcessManager.addCommand(const FakeCommand(
        command: <String>[
          'kaboom',
        ],
        exitCode: 1,
        stdout: 'stdout',
        stderr: 'stderr',
      ));
      expect(() => processUtils.runSync(<String>['kaboom'], throwOnError: true), throwsProcessException());
      expect(testLogger.statusText, contains('stdout'));
      expect(testLogger.errorText, contains('stderr'));
    });

    testWithoutContext(' does not print stdout with hideStdout', () async {
      fakeProcessManager.addCommand(const FakeCommand(
        command: <String>[
          'whoohoo',
        ],
        stdout: 'stdout',
        stderr: 'stderr',
      ));
      expect(processUtils.runSync(<String>['whoohoo'], hideStdout: true).exitCode, 0);
      expect(testLogger.traceText.contains('stdout'), isFalse);
      expect(testLogger.traceText, contains('stderr'));
    });
  });

  group('exitsHappySync', () {
    late FakeProcessManager processManager;
    late ProcessUtils processUtils;

    setUp(() {
      processManager = FakeProcessManager.empty();
      processUtils = ProcessUtils(
        processManager: processManager,
        logger: BufferLogger.test(),
      );
    });

    testWithoutContext('succeeds on success', () async {
      processManager.addCommand(const FakeCommand(
        command: <String>['whoohoo'],
      ));

      expect(processUtils.exitsHappySync(<String>['whoohoo']), isTrue);
    });

    testWithoutContext('fails on failure', () async {
      processManager.addCommand(const FakeCommand(
        command: <String>['boohoo'],
        exitCode: 1,
      ));

      expect(processUtils.exitsHappySync(<String>['boohoo']), isFalse);
    });

    testWithoutContext('catches Exception and returns false', () {
      processManager.addCommand(const FakeCommand(
        command: <String>['boohoo'],
        exception: ProcessException('Process failed', <String>[]),
      ));

      expect(processUtils.exitsHappySync(<String>['boohoo']), isFalse);
    });

    testWithoutContext('does not throw Exception and returns false if binary cannot run', () {
      processManager.excludedExecutables.add('nonesuch');

      expect(processUtils.exitsHappySync(<String>['nonesuch']), isFalse);
    });

    testWithoutContext('does not catch ArgumentError', () async {
      processManager.addCommand(FakeCommand(
        command: const <String>['invalid'],
        exception: ArgumentError('Bad input'),
      ));

      expect(
        () => processUtils.exitsHappySync(<String>['invalid']),
        throwsArgumentError,
      );
    });
  });

  group('exitsHappy', () {
    late FakeProcessManager processManager;
    late ProcessUtils processUtils;

    setUp(() {
      processManager = FakeProcessManager.empty();
      processUtils = ProcessUtils(
        processManager: processManager,
        logger: BufferLogger.test(),
      );
    });

    testWithoutContext('succeeds on success', () async {
      processManager.addCommand(const FakeCommand(
        command: <String>['whoohoo']
      ));

      expect(await processUtils.exitsHappy(<String>['whoohoo']), isTrue);
    });

    testWithoutContext('fails on failure', () async {
      processManager.addCommand(const FakeCommand(
        command: <String>['boohoo'],
        exitCode: 1,
      ));

      expect(await processUtils.exitsHappy(<String>['boohoo']), isFalse);
    });

    testWithoutContext('catches Exception and returns false', () async {
      processManager.addCommand(const FakeCommand(
        command: <String>['boohoo'],
        exception: ProcessException('Process failed', <String>[])
      ));

      expect(await processUtils.exitsHappy(<String>['boohoo']), isFalse);
    });

    testWithoutContext('does not throw Exception and returns false if binary cannot run', () async {
      processManager.excludedExecutables.add('nonesuch');

      expect(await processUtils.exitsHappy(<String>['nonesuch']), isFalse);
    });

    testWithoutContext('does not catch ArgumentError', () async {
      processManager.addCommand(FakeCommand(
        command: const <String>['invalid'],
        exception: ArgumentError('Bad input')
      ));

      expect(
        () async => processUtils.exitsHappy(<String>['invalid']),
        throwsArgumentError,
      );
    });
  });
}
