// Copyright 2013 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:io';

import 'package:image/image.dart';
import 'package:path/path.dart' as p;
import 'package:skia_gold_client/skia_gold_client.dart';

import 'environment.dart';
import 'goldens.dart';

/// Compares a screenshot taken through a test with its golden.
///
/// Used by Flutter Web Engine unit tests and the integration tests.
///
/// Returns the results of the tests as `String`. When tests passes the result
/// is simply `OK`, however when they fail it contains a detailed explanation
/// on which files are compared, their absolute locations and an HTML page
/// that the developer can see the comparison.
Future<String> compareImage(
  Image screenshot,
  bool doUpdateScreenshotGoldens,
  String filename,
  PixelComparison pixelComparison,
  double maxDiffRateFailure,
  SkiaGoldClient? skiaClient, {
  required bool isCanvaskitTest,
}) async {
  if (skiaClient == null) {
    return 'OK';
  }

  final String screenshotPath = _getFullScreenshotPath(filename);
  final File screenshotFile = File(screenshotPath);
  await screenshotFile.create(recursive: true);
  await screenshotFile.writeAsBytes(encodePng(screenshot), flush: true);

  if (isLuciEnv) {
    // This is temporary to get started by uploading existing screenshots to
    // Skia Gold. The next step would be to actually use Skia Gold for
    // comparison.
    final int screenshotSize = screenshot.width * screenshot.height;

    late int pixelColorDelta;
    if (isCanvaskitTest) {
      pixelColorDelta = 21;
    } else if (skiaClient.dimensions != null && skiaClient.dimensions!['Browser'] == 'ios-safari') {
      pixelColorDelta = 15;
    } else {
      pixelColorDelta = 3;
    }
    skiaClient.addImg(
      filename,
      screenshotFile,
      screenshotSize: screenshotSize,
      pixelColorDelta: pixelColorDelta,
    );
    return 'OK';
  }

  final Image? golden = await _getGolden(filename);

  if (doUpdateScreenshotGoldens) {
    return 'OK';
  }

  if (golden == null) {
    // This is a new screenshot that doesn't have an existing golden.

    // At the moment, we don't support local screenshot testing because we use
    // Skia Gold to handle our screenshots and diffing. In the future, we might
    // implement local screenshot testing if there's a need.
    print('Screenshot generated: file://$screenshotPath'); // ignore: avoid_print
    return 'OK';
  }

  // Compare screenshots.
  final ImageDiff diff = ImageDiff(
    golden: golden,
    other: screenshot,
    pixelComparison: pixelComparison,
  );

  if (diff.rate > 0) {
    final String testResultsPath = environment.webUiTestResultsDirectory.path;
    Directory(testResultsPath).createSync(recursive: true);
    final String basename = p.basenameWithoutExtension(filename);

    final File actualFile =
        File(p.join(testResultsPath, '$basename.actual.png'));
    actualFile.writeAsBytesSync(encodePng(screenshot), flush: true);

    final File diffFile = File(p.join(testResultsPath, '$basename.diff.png'));
    diffFile.writeAsBytesSync(encodePng(diff.diff), flush: true);

    final File expectedFile =
        File(p.join(testResultsPath, '$basename.expected.png'));
    screenshotFile.copySync(expectedFile.path);

    final File reportFile =
        File(p.join(testResultsPath, '$basename.report.html'));
    reportFile.writeAsStringSync('''
Golden file $filename did not match the image generated by the test.

<table>
  <tr>
    <th>Expected</th>
    <th>Diff</th>
    <th>Actual</th>
  </tr>
  <tr>
    <td>
      <img src="$basename.expected.png">
    </td>
    <td>
      <img src="$basename.diff.png">
    </td>
    <td>
      <img src="$basename.actual.png">
    </td>
  </tr>
</table>
''');

    final StringBuffer message = StringBuffer();
    message.writeln(
        'Golden file $filename did not match the image generated by the test.');
    message.writeln(getPrintableDiffFilesInfo(diff.rate, maxDiffRateFailure));
    message.writeln('You can view the test report in your browser by opening:');

    final String localReportPath = '$testResultsPath/$basename.report.html';
    message.writeln(localReportPath);
    message.writeln('Golden file: ${expectedFile.path}');
    message.writeln('Actual file: ${actualFile.path}');

    if (diff.rate < maxDiffRateFailure) {
      // Issue a warning but do not fail the test.
      print('WARNING:'); // ignore: avoid_print
      print(message); // ignore: avoid_print
      return 'OK';
    } else {
      // Fail test
      return '$message';
    }
  }
  return 'OK';
}

Future<Image?> _getGolden(String filename) {
  // TODO(mdebbar): Fetch the golden from Skia Gold.
  return Future<Image?>.value();
}

String _getFullScreenshotPath(String filename) {
  return p.join(environment.webUiSkiaGoldDirectory.path, filename);
}
