// 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 'dart:async';

import 'package:platform/platform.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/process.dart';
import 'package:flutter_tools/src/base/terminal.dart';
import 'package:mockito/mockito.dart';
import 'package:process/process.dart';

import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/mocks.dart' show MockProcess,
                                   MockProcessManager,
                                   MockStdio,
                                   flakyProcessFactory;

void main() {
  group('process exceptions', () {
    ProcessManager mockProcessManager;
    ProcessUtils processUtils;

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

    testWithoutContext('runAsync throwOnError: exceptions should be ProcessException objects', () async {
      when(mockProcessManager.run(<String>['false'])).thenAnswer(
          (Invocation invocation) => Future<ProcessResult>.value(ProcessResult(0, 1, '', '')));
      expect(() async => await processUtils.run(<String>['false'], throwOnError: true),
             throwsA(isA<ProcessException>()));
    });
  });

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

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

      shutdownHooks.addShutdownHook(() async {
        serializeRecording1 = i++;
      }, ShutdownStage.SERIALIZE_RECORDING);

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

      shutdownHooks.addShutdownHook(() async {
        postProcessRecording = i++;
      }, ShutdownStage.POST_PROCESS_RECORDING);

      shutdownHooks.addShutdownHook(() async {
        serializeRecording2 = i++;
      }, ShutdownStage.SERIALIZE_RECORDING);

      await shutdownHooks.runShutdownHooks();

      expect(serializeRecording1, lessThanOrEqualTo(2));
      expect(serializeRecording2, lessThanOrEqualTo(2));
      expect(postProcessRecording, 3);
      expect(cleanup, 4);
    });
  });

  group('output formatting', () {
    MockProcessManager mockProcessManager;
    ProcessUtils processUtils;
    BufferLogger mockLogger;

    setUp(() {
      mockProcessManager = MockProcessManager();
      mockLogger = BufferLogger(
        terminal: AnsiTerminal(
          stdio: MockStdio(),
          platform: FakePlatform.fromPlatform(const LocalPlatform())..stdoutSupportsAnsi = false,
        ),
        outputPreferences: OutputPreferences(wrapText: true, wrapColumn: 40),
      );
      processUtils = ProcessUtils(
        processManager: mockProcessManager,
        logger: mockLogger,
      );
    });

    MockProcess Function(List<String>) processMetaFactory(List<String> stdout, {
      List<String> stderr = const <String>[],
    }) {
      final Stream<List<int>> stdoutStream = Stream<List<int>>.fromIterable(
        stdout.map<List<int>>((String s) => s.codeUnits,
      ));
      final Stream<List<int>> stderrStream = Stream<List<int>>.fromIterable(
        stderr.map<List<int>>((String s) => s.codeUnits,
      ));
      return (List<String> command) => MockProcess(stdout: stdoutStream, stderr: stderrStream);
    }

    testWithoutContext('Command output is not wrapped.', () async {
      final List<String> testString = <String>['0123456789' * 10];
      mockProcessManager.processFactory = processMetaFactory(testString, stderr: testString);
      await processUtils.stream(<String>['command']);
      expect(mockLogger.statusText, equals('${testString[0]}\n'));
      expect(mockLogger.errorText, equals('${testString[0]}\n'));
    });
  });

  group('run', () {
    const Duration delay = Duration(seconds: 2);
    MockProcessManager flakyProcessManager;
    ProcessManager mockProcessManager;
    ProcessUtils processUtils;
    ProcessUtils flakyProcessUtils;

    setUp(() {
      // MockProcessManager has an implementation of start() that returns the
      // result of processFactory.
      flakyProcessManager = MockProcessManager();
      mockProcessManager = MockProcessManager();
      processUtils = ProcessUtils(
        processManager: mockProcessManager,
        logger: BufferLogger.test(),
      );
      flakyProcessUtils = ProcessUtils(
        processManager: flakyProcessManager,
        logger: BufferLogger.test(),
      );
    });

    testWithoutContext(' succeeds on success', () async {
      when(mockProcessManager.run(<String>['whoohoo'])).thenAnswer((_) {
        return Future<ProcessResult>.value(ProcessResult(0, 0, '', ''));
      });
      expect((await processUtils.run(<String>['whoohoo'])).exitCode, 0);
    });

    testWithoutContext(' fails on failure', () async {
      when(mockProcessManager.run(<String>['boohoo'])).thenAnswer((_) {
        return Future<ProcessResult>.value(ProcessResult(0, 1, '', ''));
      });
      expect((await processUtils.run(<String>['boohoo'])).exitCode, 1);
    });

    testWithoutContext(' throws on failure with throwOnError', () async {
      when(mockProcessManager.run(<String>['kaboom'])).thenAnswer((_) {
        return Future<ProcessResult>.value(ProcessResult(0, 1, '', ''));
      });
      expect(() => processUtils.run(<String>['kaboom'], throwOnError: true),
             throwsA(isA<ProcessException>()));
    });

    testWithoutContext(' does not throw on failure with whitelist', () async {
      when(mockProcessManager.run(<String>['kaboom'])).thenAnswer((_) {
        return Future<ProcessResult>.value(ProcessResult(0, 1, '', ''));
      });
      expect(
        (await processUtils.run(
          <String>['kaboom'],
          throwOnError: true,
          whiteListFailures: (int c) => c == 1,
        )).exitCode,
        1,
      );
    });

    testWithoutContext(' throws on failure when not in whitelist', () async {
      when(mockProcessManager.run(<String>['kaboom'])).thenAnswer((_) {
        return Future<ProcessResult>.value(ProcessResult(0, 2, '', ''));
      });
      expect(
        () => processUtils.run(
          <String>['kaboom'],
          throwOnError: true,
          whiteListFailures: (int c) => c == 1,
        ),
        throwsA(isA<ProcessException>()),
      );
    });

    testWithoutContext(' flaky process fails without retry', () async {
      flakyProcessManager.processFactory = flakyProcessFactory(
        flakes: 1,
        delay: delay,
      );
      final RunResult result = await flakyProcessUtils.run(
        <String>['dummy'],
        timeout: delay + const Duration(seconds: 1),
      );
      expect(result.exitCode, -9);
    });

    testWithoutContext(' flaky process succeeds with retry', () async {
      flakyProcessManager.processFactory = flakyProcessFactory(
        flakes: 1,
        delay: delay,
      );
      final RunResult result = await flakyProcessUtils.run(
        <String>['dummy'],
        timeout: delay - const Duration(milliseconds: 500),
        timeoutRetries: 1,
      );
      expect(result.exitCode, 0);
    });

    testWithoutContext(' flaky process generates ProcessException on timeout', () async {
      final Completer<List<int>> flakyStderr = Completer<List<int>>();
      final Completer<List<int>> flakyStdout = Completer<List<int>>();
      flakyProcessManager.processFactory = flakyProcessFactory(
        flakes: 1,
        delay: delay,
        stderr: () => Stream<List<int>>.fromFuture(flakyStderr.future),
        stdout: () => Stream<List<int>>.fromFuture(flakyStdout.future),
      );
      when(flakyProcessManager.killPid(any)).thenAnswer((_) {
        // Don't let the stderr stream stop until the process is killed. This
        // ensures that runAsync() does not delay killing the process until
        // stdout and stderr are drained (which won't happen).
        flakyStderr.complete(<int>[]);
        flakyStdout.complete(<int>[]);
        return true;
      });
      expect(() => flakyProcessUtils.run(
        <String>['dummy'],
        timeout: delay - const Duration(milliseconds: 500),
        timeoutRetries: 0,
      ), throwsA(isA<ProcessException>()));
    });
  });

  group('runSync', () {
    ProcessManager mockProcessManager;
    ProcessUtils processUtils;
    BufferLogger testLogger;

    setUp(() {
      mockProcessManager = MockProcessManager();
      testLogger = BufferLogger(
        terminal: AnsiTerminal(
          stdio: MockStdio(),
          platform: FakePlatform.fromPlatform(const LocalPlatform())..stdoutSupportsAnsi = false,
        ),
        outputPreferences: OutputPreferences(wrapText: true, wrapColumn: 40),
      );
      processUtils = ProcessUtils(
        processManager: mockProcessManager,
        logger: testLogger,
      );
    });

    testWithoutContext(' succeeds on success', () async {
      when(mockProcessManager.runSync(<String>['whoohoo'])).thenReturn(
        ProcessResult(0, 0, '', '')
      );
      expect(processUtils.runSync(<String>['whoohoo']).exitCode, 0);
    });

    testWithoutContext(' fails on failure', () async {
      when(mockProcessManager.runSync(<String>['boohoo'])).thenReturn(
        ProcessResult(0, 1, '', '')
      );
      expect(processUtils.runSync(<String>['boohoo']).exitCode, 1);
    });

    testWithoutContext(' throws on failure with throwOnError', () async {
      when(mockProcessManager.runSync(<String>['kaboom'])).thenReturn(
        ProcessResult(0, 1, '', '')
      );
      expect(() => processUtils.runSync(<String>['kaboom'], throwOnError: true),
             throwsA(isA<ProcessException>()));
    });

    testWithoutContext(' does not throw on failure with whitelist', () async {
      when(mockProcessManager.runSync(<String>['kaboom'])).thenReturn(
        ProcessResult(0, 1, '', '')
      );
      expect(
        processUtils.runSync(
          <String>['kaboom'],
          throwOnError: true,
          whiteListFailures: (int c) => c == 1,
        ).exitCode,
        1);
    });

    testWithoutContext(' throws on failure when not in whitelist', () async {
      when(mockProcessManager.runSync(<String>['kaboom'])).thenReturn(
        ProcessResult(0, 2, '', '')
      );
      expect(
        () => processUtils.runSync(
          <String>['kaboom'],
          throwOnError: true,
          whiteListFailures: (int c) => c == 1,
        ),
        throwsA(isA<ProcessException>()));
    });

    testWithoutContext(' prints stdout and stderr to trace on success', () async {
      when(mockProcessManager.runSync(<String>['whoohoo'])).thenReturn(
        ProcessResult(0, 0, 'stdout', '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 {
      when(mockProcessManager.runSync(<String>['kaboom'])).thenReturn(
        ProcessResult(0, 1, 'stdout', 'stderr')
      );
      expect(() => processUtils.runSync(<String>['kaboom'], throwOnError: true),
             throwsA(isA<ProcessException>()));
      expect(testLogger.statusText, contains('stdout'));
      expect(testLogger.errorText, contains('stderr'));
    });

    testWithoutContext(' does not print stdout with hideStdout', () async {
      when(mockProcessManager.runSync(<String>['whoohoo'])).thenReturn(
        ProcessResult(0, 0, 'stdout', 'stderr')
      );
      expect(processUtils.runSync(<String>['whoohoo'], hideStdout: true).exitCode, 0);
      expect(testLogger.traceText.contains('stdout'), isFalse);
      expect(testLogger.traceText, contains('stderr'));
    });
  });

  group('exitsHappySync', () {
    MockProcessManager mockProcessManager;
    ProcessUtils processUtils;

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

    testWithoutContext(' succeeds on success', () async {
      when(mockProcessManager.runSync(<String>['whoohoo'])).thenReturn(
        ProcessResult(0, 0, '', '')
      );
      expect(processUtils.exitsHappySync(<String>['whoohoo']), isTrue);
    });

    testWithoutContext(' fails on failure', () async {
      when(mockProcessManager.runSync(<String>['boohoo'])).thenReturn(
        ProcessResult(0, 1, '', '')
      );
      expect(processUtils.exitsHappySync(<String>['boohoo']), isFalse);
    });

    testWithoutContext('catches Exception and returns false', () {
      when(mockProcessManager.runSync(<String>['boohoo'])).thenThrow(
        const ProcessException('Process failed', <String>[]),
      );
      expect(processUtils.exitsHappySync(<String>['boohoo']), isFalse);
    });

    testWithoutContext('does not throw Exception and returns false if binary cannot run', () {
      mockProcessManager.canRunSucceeds = false;
      expect(processUtils.exitsHappySync(<String>['nonesuch']), isFalse);
      verifyNever(
        mockProcessManager.runSync(any, environment: anyNamed('environment')),
      );
    });

    testWithoutContext('does not catch ArgumentError', () async {
      when(mockProcessManager.runSync(<String>['invalid'])).thenThrow(
        ArgumentError('Bad input'),
      );
      expect(
        () => processUtils.exitsHappySync(<String>['invalid']),
        throwsArgumentError,
      );
    });
  });

  group('exitsHappy', () {
    MockProcessManager mockProcessManager;
    ProcessUtils processUtils;

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

    testWithoutContext('succeeds on success', () async {
      when(mockProcessManager.run(<String>['whoohoo'])).thenAnswer((_) {
        return Future<ProcessResult>.value(ProcessResult(0, 0, '', ''));
      });
      expect(await processUtils.exitsHappy(<String>['whoohoo']), isTrue);
    });

    testWithoutContext('fails on failure', () async {
      when(mockProcessManager.run(<String>['boohoo'])).thenAnswer((_) {
        return Future<ProcessResult>.value(ProcessResult(0, 1, '', ''));
      });
      expect(await processUtils.exitsHappy(<String>['boohoo']), isFalse);
    });

    testWithoutContext('catches Exception and returns false', () async {
      when(mockProcessManager.run(<String>['boohoo'])).thenThrow(
        const ProcessException('Process failed', <String>[]),
      );
      expect(await processUtils.exitsHappy(<String>['boohoo']), isFalse);
    });

    testWithoutContext('does not throw Exception and returns false if binary cannot run', () async {
      mockProcessManager.canRunSucceeds = false;
      expect(await processUtils.exitsHappy(<String>['nonesuch']), isFalse);
      verifyNever(
        mockProcessManager.runSync(any, environment: anyNamed('environment')),
      );
    });

    testWithoutContext('does not catch ArgumentError', () async {
      when(mockProcessManager.run(<String>['invalid'])).thenThrow(
        ArgumentError('Bad input'),
      );
      expect(
        () async => await processUtils.exitsHappy(<String>['invalid']),
        throwsArgumentError,
      );
    });
  });

}

class PlainMockProcessManager extends Mock implements ProcessManager {}
