// 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();

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

      await shutdownHooks.runShutdownHooks(BufferLogger.test());

      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,
      );
    });
  });
}
