// 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/test/flutter_web_platform.dart';
import 'package:flutter_tools/src/test/test_compiler.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
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(globals.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 {}
