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

import 'package:process/process.dart';

import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../convert.dart';
import '../web/compile.dart';
import 'test_compiler.dart';
import 'test_config.dart';

/// Helper class to start golden file comparison in a separate process.
///
/// The golden file comparator is configured using flutter_test_config.dart and that
/// file can contain arbitrary Dart code that depends on dart:ui. Thus it has to
/// be executed in a `flutter_tester` environment. This helper class generates a
/// Dart file configured with flutter_test_config.dart to perform the comparison
/// of golden files.
class TestGoldenComparator {
  /// Creates a [TestGoldenComparator] instance.
  TestGoldenComparator(this.shellPath, this.compilerFactory, {
    required Logger logger,
    required FileSystem fileSystem,
    required ProcessManager processManager,
    required this.webRenderer,
  }) : tempDir = fileSystem.systemTempDirectory.createTempSync('flutter_web_platform.'),
       _logger = logger,
       _fileSystem = fileSystem,
       _processManager = processManager;

  final String? shellPath;
  final Directory tempDir;
  final TestCompiler Function() compilerFactory;
  final Logger _logger;
  final FileSystem _fileSystem;
  final ProcessManager _processManager;
  final WebRendererMode webRenderer;

  TestCompiler? _compiler;
  TestGoldenComparatorProcess? _previousComparator;
  Uri? _previousTestUri;

  Future<void> close() async {
    tempDir.deleteSync(recursive: true);
    await _compiler?.dispose();
    await _previousComparator?.close();
  }

  /// Start golden comparator in a separate process. Start one file per test file
  /// to reduce the overhead of starting `flutter_tester`.
  Future<TestGoldenComparatorProcess?> _processForTestFile(Uri testUri) async {
    if (testUri == _previousTestUri) {
      return _previousComparator!;
    }

    final String bootstrap = TestGoldenComparatorProcess.generateBootstrap(_fileSystem.file(testUri), testUri, logger: _logger);
    final Process? process = await _startProcess(bootstrap);
    if (process == null) {
      return null;
    }
    unawaited(_previousComparator?.close());
    _previousComparator = TestGoldenComparatorProcess(process, logger: _logger);
    _previousTestUri = testUri;

    return _previousComparator!;
  }

  Future<Process?> _startProcess(String testBootstrap) async {
    // Prepare the Dart file that will talk to us and start the test.
    final File listenerFile = (await tempDir.createTemp('listener')).childFile('listener.dart');
    await listenerFile.writeAsString(testBootstrap);

    // Lazily create the compiler
    _compiler = _compiler ?? compilerFactory();
    final String? output = await _compiler!.compile(listenerFile.uri);
    if (output == null) {
      return null;
    }
    final List<String> command = <String>[
      shellPath!,
      '--disable-vm-service',
      '--non-interactive',
      '--packages=${_fileSystem.path.join('.dart_tool', 'package_config.json')}',
      output,
    ];

    final Map<String, String> environment = <String, String>{
      // Chrome is the only supported browser currently.
      'FLUTTER_TEST_BROWSER': 'chrome',
      'FLUTTER_WEB_RENDERER': webRenderer.name,
    };
    return _processManager.start(command, environment: environment);
  }

  Future<String?> compareGoldens(Uri testUri, Uint8List bytes, Uri goldenKey, bool? updateGoldens) async {
    final File imageFile = await (await tempDir.createTemp('image')).childFile('image').writeAsBytes(bytes);
    final TestGoldenComparatorProcess? process = await _processForTestFile(testUri);
    if (process == null) {
      return 'process was null';
    }

    process.sendCommand(imageFile, goldenKey, updateGoldens);

    final Map<String, dynamic> result = await process.getResponse();
    return (result['success'] as bool) ? null : ((result['message'] as String?) ?? 'does not match');
  }
}

/// Represents a `flutter_tester` process started for golden comparison. Also
/// handles communication with the child process.
class TestGoldenComparatorProcess {
  /// Creates a [TestGoldenComparatorProcess] backed by [process].
  TestGoldenComparatorProcess(this.process, {required Logger logger}) : _logger = logger {
    // Pipe stdout and stderr to printTrace and printError.
    // Also parse stdout as a stream of JSON objects.
    streamIterator = StreamIterator<Map<String, dynamic>>(
      process.stdout
        .transform<String>(utf8.decoder)
        .transform<String>(const LineSplitter())
        .where((String line) {
          logger.printTrace('<<< $line');
          return line.isNotEmpty && line[0] == '{';
        })
        .map<dynamic>(jsonDecode)
        .cast<Map<String, dynamic>>());

    process.stderr
        .transform<String>(utf8.decoder)
        .transform<String>(const LineSplitter())
        .forEach((String line) {
          logger.printError('<<< $line');
        });
  }

  final Logger _logger;
  final Process process;
  late StreamIterator<Map<String, dynamic>> streamIterator;

  Future<void> close() async {
    process.kill();
    await process.exitCode;
  }

  void sendCommand(File imageFile, Uri? goldenKey, bool? updateGoldens) {
    final Object command = jsonEncode(<String, dynamic>{
      'imageFile': imageFile.path,
      'key': goldenKey.toString(),
      'update': updateGoldens,
    });
    _logger.printTrace('Preparing to send command: $command');
    process.stdin.writeln(command);
  }

  Future<Map<String, dynamic>> getResponse() async {
    final bool available = await streamIterator.moveNext();
    assert(available);
    return streamIterator.current;
  }

  static String generateBootstrap(File testFile, Uri testUri, {required Logger logger}) {
    final File? testConfigFile = findTestConfigFile(testFile, logger);
    // Generate comparator process for the file.
    return '''
import 'dart:convert'; // flutter_ignore: dart_convert_import
import 'dart:io'; // flutter_ignore: dart_io_import

import 'package:flutter_test/flutter_test.dart';

${testConfigFile != null ? "import '${Uri.file(testConfigFile.path)}' as test_config;" : ""}

void main() async {
  LocalFileComparator comparator = LocalFileComparator(Uri.parse('$testUri'));
  goldenFileComparator = comparator;

  ${testConfigFile != null ? 'test_config.testExecutable(() async {' : ''}
  final commands = stdin
    .transform<String>(utf8.decoder)
    .transform<String>(const LineSplitter())
    .map<dynamic>(jsonDecode);
  await for (final dynamic command in commands) {
    if (command is Map<String, dynamic>) {
      File imageFile = File(command['imageFile'] as String);
      Uri goldenKey = Uri.parse(command['key'] as String);
      bool update = command['update'] as bool;

      final bytes = await File(imageFile.path).readAsBytes();
      if (update) {
        await goldenFileComparator.update(goldenKey, bytes);
        print(jsonEncode({'success': true}));
      } else {
        try {
          bool success = await goldenFileComparator.compare(bytes, goldenKey);
          print(jsonEncode({'success': success}));
        } on Exception catch (ex) {
          print(jsonEncode({'success': false, 'message': '\$ex'}));
        }
      }
    } else {
      print('object type is not right');
    }
  }
  ${testConfigFile != null ? '});' : ''}
}
    ''';
  }
}
