// 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: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', () {
    late 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 { }
}
