// 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/terminal.dart';
import 'package:mockito/mockito.dart';

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

void main() {
  group('output preferences', () {
    testWithoutContext('can wrap output', () async {
      final BufferLogger bufferLogger = BufferLogger(
        outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40),
        terminal: TestTerminal(platform: FakePlatform()..stdoutSupportsAnsi = true),
      );
      bufferLogger.printStatus('0123456789' * 8);

      expect(bufferLogger.statusText, equals(('0123456789' * 4 + '\n') * 2));
    });

    testWithoutContext('can turn off wrapping', () async {
      final BufferLogger bufferLogger = BufferLogger(
        outputPreferences: OutputPreferences.test(wrapText: false),
        terminal: TestTerminal(platform: FakePlatform()..stdoutSupportsAnsi = true),
      );
      final String testString = '0123456789' * 20;
      bufferLogger.printStatus(testString);

      expect(bufferLogger.statusText, equals('$testString\n'));
    });
  });

  group('ANSI coloring and bold', () {
    AnsiTerminal terminal;

    setUp(() {
      terminal = AnsiTerminal(
        stdio: Stdio(), // Danger, using real stdio.
        platform: FakePlatform()..stdoutSupportsAnsi = true,
      );
    });

    testWithoutContext('adding colors works', () {
      for (final TerminalColor color in TerminalColor.values) {
        expect(
          terminal.color('output', color),
          equals('${AnsiTerminal.colorCode(color)}output${AnsiTerminal.resetColor}'),
        );
      }
    });

    testWithoutContext('adding bold works', () {
      expect(
        terminal.bolden('output'),
        equals('${AnsiTerminal.bold}output${AnsiTerminal.resetBold}'),
      );
    });

    testWithoutContext('nesting bold within color works', () {
      expect(
        terminal.color(terminal.bolden('output'), TerminalColor.blue),
        equals('${AnsiTerminal.blue}${AnsiTerminal.bold}output${AnsiTerminal.resetBold}${AnsiTerminal.resetColor}'),
      );
      expect(
        terminal.color('non-bold ${terminal.bolden('output')} also non-bold', TerminalColor.blue),
        equals('${AnsiTerminal.blue}non-bold ${AnsiTerminal.bold}output${AnsiTerminal.resetBold} also non-bold${AnsiTerminal.resetColor}'),
      );
    });

    testWithoutContext('nesting color within bold works', () {
      expect(
        terminal.bolden(terminal.color('output', TerminalColor.blue)),
        equals('${AnsiTerminal.bold}${AnsiTerminal.blue}output${AnsiTerminal.resetColor}${AnsiTerminal.resetBold}'),
      );
      expect(
        terminal.bolden('non-color ${terminal.color('output', TerminalColor.blue)} also non-color'),
        equals('${AnsiTerminal.bold}non-color ${AnsiTerminal.blue}output${AnsiTerminal.resetColor} also non-color${AnsiTerminal.resetBold}'),
      );
    });

    testWithoutContext('nesting color within color works', () {
      expect(
        terminal.color(terminal.color('output', TerminalColor.blue), TerminalColor.magenta),
        equals('${AnsiTerminal.magenta}${AnsiTerminal.blue}output${AnsiTerminal.resetColor}${AnsiTerminal.magenta}${AnsiTerminal.resetColor}'),
      );
      expect(
        terminal.color('magenta ${terminal.color('output', TerminalColor.blue)} also magenta', TerminalColor.magenta),
        equals('${AnsiTerminal.magenta}magenta ${AnsiTerminal.blue}output${AnsiTerminal.resetColor}${AnsiTerminal.magenta} also magenta${AnsiTerminal.resetColor}'),
      );
    });

    testWithoutContext('nesting bold within bold works', () {
      expect(
        terminal.bolden(terminal.bolden('output')),
        equals('${AnsiTerminal.bold}output${AnsiTerminal.resetBold}'),
      );
      expect(
        terminal.bolden('bold ${terminal.bolden('output')} still bold'),
        equals('${AnsiTerminal.bold}bold output still bold${AnsiTerminal.resetBold}'),
      );
    });
  });

  group('character input prompt', () {
    AnsiTerminal terminalUnderTest;

    setUp(() {
      terminalUnderTest = TestTerminal(stdio: MockStdio());
    });

    testWithoutContext('character prompt throws if usesTerminalUi is false', () async {
      expect(terminalUnderTest.promptForCharInput(
        <String>['a', 'b', 'c'],
        prompt: 'Please choose something',
        logger: null,
      ), throwsStateError);
    });

    testWithoutContext('character prompt', () async {
      final BufferLogger bufferLogger = BufferLogger(
        terminal: terminalUnderTest,
        outputPreferences: OutputPreferences.test(),
      );
      terminalUnderTest.usesTerminalUi = true;
      mockStdInStream = Stream<String>.fromFutures(<Future<String>>[
        Future<String>.value('d'), // Not in accepted list.
        Future<String>.value('\n'), // Not in accepted list
        Future<String>.value('b'),
      ]).asBroadcastStream();
      final String choice = await terminalUnderTest.promptForCharInput(
        <String>['a', 'b', 'c'],
        prompt: 'Please choose something',
        logger: bufferLogger,
      );
      expect(choice, 'b');
      expect(
          bufferLogger.statusText,
          'Please choose something [a|b|c]: d\n'
          'Please choose something [a|b|c]: \n'
          'Please choose something [a|b|c]: b\n');
    });

    testWithoutContext('default character choice without displayAcceptedCharacters', () async {
      final BufferLogger bufferLogger = BufferLogger(
        terminal: terminalUnderTest,
        outputPreferences: OutputPreferences.test(),
      );
      terminalUnderTest.usesTerminalUi = true;
      mockStdInStream = Stream<String>.fromFutures(<Future<String>>[
        Future<String>.value('\n'), // Not in accepted list
      ]).asBroadcastStream();
      final String choice = await terminalUnderTest.promptForCharInput(
        <String>['a', 'b', 'c'],
        prompt: 'Please choose something',
        displayAcceptedCharacters: false,
        defaultChoiceIndex: 1, // which is b.
        logger: bufferLogger,
      );

      expect(choice, 'b');
      expect(
        bufferLogger.statusText,
        'Please choose something: \n'
      );
    });

    testWithoutContext('Does not set single char mode when a terminal is not attached', () {
      final Stdio stdio = MockStdio();
      when(stdio.stdin).thenThrow(StateError('This should not be called'));
      when(stdio.stdinHasTerminal).thenReturn(false);
      final AnsiTerminal ansiTerminal = AnsiTerminal(
        stdio: stdio,
        platform: const LocalPlatform()
      );

      expect(() => ansiTerminal.singleCharMode = true, returnsNormally);
    });
  });
}

Stream<String> mockStdInStream;

class TestTerminal extends AnsiTerminal {
  TestTerminal({
    Stdio stdio,
    Platform platform = const LocalPlatform(),
  }) : super(stdio: stdio, platform: platform);

  @override
  Stream<String> get keystrokes {
    return mockStdInStream;
  }

  bool singleCharMode = false;
}

class MockStdio extends Mock implements Stdio {}
