// 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 'dart:convert';
import 'dart:typed_data';

import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/test/flutter_web_platform.dart';
import 'package:flutter_tools/src/test/test_compiler.dart';
import 'package:mockito/mockito.dart';
import 'package:process/process.dart';

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

void main() {

  group('Test that TestGoldenComparator', () {
    Testbed testbed;
    Uri goldenKey;
    Uri goldenKey2;
    Uri testUri;
    Uri testUri2;
    Uint8List imageBytes;
    MockProcessManager mockProcessManager;
    MockTestCompiler mockCompiler;

    setUp(() {
      goldenKey = Uri.parse('file://golden_key');
      goldenKey2 = Uri.parse('file://second_golden_key');
      testUri = Uri.parse('file://test_uri');
      testUri2 = Uri.parse('file://second_test_uri');
      imageBytes = Uint8List.fromList(<int>[1,2,3,4,5]);
      mockProcessManager = MockProcessManager();
      mockCompiler = MockTestCompiler();
      when(mockCompiler.compile(any)).thenAnswer((_) => Future<String>.value('compiler_output'));

      testbed = Testbed(overrides: <Type, Generator>{
        ProcessManager: () {
          print('in get process manager');
          return mockProcessManager;
        }
      });
    });

    test('succeed when golden comparison succeed', () => testbed.run(() async {
      final Map<String, dynamic> expectedResponse = <String, dynamic>{
        'success': true,
        'message': 'some message',
      };

      when(mockProcessManager.start(any, environment: anyNamed('environment')))
        .thenAnswer((Invocation invocation) async {
          return FakeProcess(
            exitCode: Future<int>.value(0),
            stdout: stdoutFromString(jsonEncode(expectedResponse) + '\n'),
          );
      });

      final TestGoldenComparator comparator = TestGoldenComparator(
        'shell',
        () => mockCompiler,
      );

      final String result = await comparator.compareGoldens(testUri, imageBytes, goldenKey, false);
      expect(result, null);
    }));

    test('fail with error message when golden comparison failed', () => testbed.run(() async {
      final Map<String, dynamic> expectedResponse = <String, dynamic>{
        'success': false,
        'message': 'some message',
      };

      when(mockProcessManager.start(any, environment: anyNamed('environment')))
        .thenAnswer((Invocation invocation) async {
          return FakeProcess(
            exitCode: Future<int>.value(0),
            stdout: stdoutFromString(jsonEncode(expectedResponse) + '\n'),
          );
      });

      final TestGoldenComparator comparator = TestGoldenComparator(
        'shell',
        () => mockCompiler,
      );

      final String result = await comparator.compareGoldens(testUri, imageBytes, goldenKey, false);
      expect(result, 'some message');
    }));

    test('reuse the process for the same test file', () => testbed.run(() async {
      final Map<String, dynamic> expectedResponse1 = <String, dynamic>{
        'success': false,
        'message': 'some message',
      };
      final Map<String, dynamic> expectedResponse2 = <String, dynamic>{
        'success': false,
        'message': 'some other message',
      };

      when(mockProcessManager.start(any, environment: anyNamed('environment')))
        .thenAnswer((Invocation invocation) async {
          return FakeProcess(
            exitCode: Future<int>.value(0),
            stdout: stdoutFromString(jsonEncode(expectedResponse1) + '\n' + jsonEncode(expectedResponse2) + '\n'),
          );
      });

      final TestGoldenComparator comparator = TestGoldenComparator(
        'shell',
        () => mockCompiler,
      );

      final String result1 = await comparator.compareGoldens(testUri, imageBytes, goldenKey, false);
      expect(result1, 'some message');
      final String result2 = await comparator.compareGoldens(testUri, imageBytes, goldenKey2, false);
      expect(result2, 'some other message');
      verify(mockProcessManager.start(any, environment: anyNamed('environment'))).called(1);
    }));

    test('does not reuse the process for different test file', () => testbed.run(() async {
      final Map<String, dynamic> expectedResponse1 = <String, dynamic>{
        'success': false,
        'message': 'some message',
      };
      final Map<String, dynamic> expectedResponse2 = <String, dynamic>{
        'success': false,
        'message': 'some other message',
      };

      when(mockProcessManager.start(any, environment: anyNamed('environment')))
        .thenAnswer((Invocation invocation) async {
          return FakeProcess(
            exitCode: Future<int>.value(0),
            stdout: stdoutFromString(jsonEncode(expectedResponse1) + '\n' + jsonEncode(expectedResponse2) + '\n'),
          );
      });

      final TestGoldenComparator comparator = TestGoldenComparator(
        'shell',
        () => mockCompiler,
      );

      final String result1 = await comparator.compareGoldens(testUri, imageBytes, goldenKey, false);
      expect(result1, 'some message');
      final String result2 = await comparator.compareGoldens(testUri2, imageBytes, goldenKey2, false);
      expect(result2, 'some message');
      verify(mockProcessManager.start(any, environment: anyNamed('environment'))).called(2);
    }));

    test('removes all temporary files when closed', () => testbed.run(() async {
      final Map<String, dynamic> expectedResponse = <String, dynamic>{
        'success': true,
        'message': 'some message',
      };

      when(mockProcessManager.start(any, environment: anyNamed('environment')))
        .thenAnswer((Invocation invocation) async {
          return FakeProcess(
            exitCode: Future<int>.value(0),
            stdout: stdoutFromString(jsonEncode(expectedResponse) + '\n'),
          );
      });

      final TestGoldenComparator comparator = TestGoldenComparator(
        'shell',
        () => mockCompiler,
      );

      final String result = await comparator.compareGoldens(testUri, imageBytes, goldenKey, false);
      expect(result, null);

      await comparator.close();
      expect(fs.systemTempDirectory.listSync(recursive: true), isEmpty);
    }));
  });
}

Stream<List<int>> stdoutFromString(String string) => Stream<List<int>>.fromIterable(<List<int>>[
  utf8.encode(string),
]);

class MockProcessManager extends Mock implements ProcessManager {}
class MockTestCompiler extends Mock implements TestCompiler {}
