// 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.

// @dart = 2.8

import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';

import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/test/flutter_web_goldens.dart';
import 'package:flutter_tools/src/test/test_compiler.dart';
import 'package:flutter_tools/src/web/compile.dart';
import 'package:test/fake.dart';

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

final Uri goldenKey = Uri.parse('file://golden_key');
final Uri goldenKey2 = Uri.parse('file://second_golden_key');
final Uri testUri = Uri.parse('file://test_uri');
final Uri testUri2  = Uri.parse('file://second_test_uri');
final Uint8List imageBytes = Uint8List.fromList(<int>[1, 2, 3, 4, 5]);

void main() {

  group('Test that TestGoldenComparator', () {
    FakeProcessManager processManager;

    setUp(() {
      processManager = FakeProcessManager.empty();
    });

    testWithoutContext('succeed when golden comparison succeed', () async {
      final Map<String, dynamic> expectedResponse = <String, dynamic>{
        'success': true,
        'message': 'some message',
      };
      processManager.addCommand(FakeCommand(
        command: const <String>[
          'shell',
          '--disable-observatory',
          '--non-interactive',
          '--packages=.dart_tool/package_config.json',
          'compiler_output'
        ],
        stdout: '${jsonEncode(expectedResponse)}\n',
        environment: const <String, String>{
          'FLUTTER_TEST_BROWSER': 'chrome',
          'FLUTTER_WEB_RENDERER': 'html',
        },
      ));

      final TestGoldenComparator comparator = TestGoldenComparator(
        'shell',
        () => FakeTestCompiler(),
        processManager: processManager,
        fileSystem: MemoryFileSystem.test(),
        logger: BufferLogger.test(),
        webRenderer: WebRendererMode.html,
      );

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

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

      processManager.addCommand(FakeCommand(
        command: const <String>[
          'shell',
          '--disable-observatory',
          '--non-interactive',
          '--packages=.dart_tool/package_config.json',
          'compiler_output'
        ], stdout: '${jsonEncode(expectedResponse)}\n',
      ));

      final TestGoldenComparator comparator = TestGoldenComparator(
        'shell',
        () => FakeTestCompiler(),
        processManager: processManager,
        fileSystem: MemoryFileSystem.test(),
        logger: BufferLogger.test(),
        webRenderer: WebRendererMode.canvaskit,
      );

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

    testWithoutContext('reuse the process for the same test file', () 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',
      };

      processManager.addCommand(FakeCommand(
        command: const <String>[
          'shell',
          '--disable-observatory',
          '--non-interactive',
          '--packages=.dart_tool/package_config.json',
          'compiler_output'
        ], stdout: '${jsonEncode(expectedResponse1)}\n${jsonEncode(expectedResponse2)}\n',
      ));

      final TestGoldenComparator comparator = TestGoldenComparator(
        'shell',
        () => FakeTestCompiler(),
        processManager: processManager,
        fileSystem: MemoryFileSystem.test(),
        logger: BufferLogger.test(),
        webRenderer: WebRendererMode.html,
      );

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

    testWithoutContext('does not reuse the process for different test file', () 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',
      };

      processManager.addCommand(FakeCommand(
        command: const <String>[
          'shell',
          '--disable-observatory',
          '--non-interactive',
          '--packages=.dart_tool/package_config.json',
          'compiler_output'
        ], stdout: '${jsonEncode(expectedResponse1)}\n',
      ));
      processManager.addCommand(FakeCommand(
        command: const <String>[
          'shell',
          '--disable-observatory',
          '--non-interactive',
          '--packages=.dart_tool/package_config.json',
          'compiler_output'
        ], stdout: '${jsonEncode(expectedResponse2)}\n',
      ));

      final TestGoldenComparator comparator = TestGoldenComparator(
        'shell',
        () => FakeTestCompiler(),
        processManager: processManager,
        fileSystem: MemoryFileSystem.test(),
        logger: BufferLogger.test(),
        webRenderer: WebRendererMode.canvaskit,
      );

      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 other message');
    });

    testWithoutContext('removes all temporary files when closed', () async {
      final FileSystem fileSystem = MemoryFileSystem.test();
      final Map<String, dynamic> expectedResponse = <String, dynamic>{
        'success': true,
        'message': 'some message',
      };
      final StreamController<List<int>> controller = StreamController<List<int>>();
      final IOSink stdin = IOSink(controller.sink);
      processManager.addCommand(FakeCommand(
        command: const <String>[
          'shell',
          '--disable-observatory',
          '--non-interactive',
          '--packages=.dart_tool/package_config.json',
          'compiler_output'
        ], stdout: '${jsonEncode(expectedResponse)}\n',
        stdin: stdin,
      ));

      final TestGoldenComparator comparator = TestGoldenComparator(
        'shell',
        () => FakeTestCompiler(),
        processManager: processManager,
        fileSystem: fileSystem,
        logger: BufferLogger.test(),
        webRenderer: WebRendererMode.html,
      );

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

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

class FakeTestCompiler extends Fake implements TestCompiler {
  @override
  Future<String> compile(Uri mainDart) {
    return Future<String>.value('compiler_output');
  }

  @override
  Future<void> dispose() async { }
}
