// Copyright 2018 The Chromium 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:io';
import 'dart:typed_data';

import 'package:path/path.dart' as path;
import 'package:test/test.dart' show TestFailure;

/// Compares rasterized image bytes against a golden image file.
///
/// Instances of this comparator will be used as the backend for
/// [matchesGoldenFile].
///
/// Instances of this comparator will be invoked by the test framework in the
/// [TestWidgetsFlutterBinding.runAsync] zone and are thus not subject to the
/// fake async constraints that are normally imposed on widget tests (i.e. the
/// need or the ability to call [WidgetTester.pump] to advance the microtask
/// queue).
abstract class GoldenFileComparator {
  /// Compares [imageBytes] against the golden file identified by [golden].
  ///
  /// The returned future completes with a boolean value that indicates whether
  /// [imageBytes] matches the golden file's bytes within the tolerance defined
  /// by the comparator.
  ///
  /// In the case of comparison mismatch, the comparator may choose to throw a
  /// [TestFailure] if it wants to control the failure message.
  ///
  /// The method by which [golden] is located and by which its bytes are loaded
  /// is left up to the implementation class. For instance, some implementations
  /// may load files from the local file system, whereas others may load files
  /// over the network or from a remote repository.
  Future<bool> compare(Uint8List imageBytes, Uri golden);

  /// Updates the golden file identified by [golden] with [imageBytes].
  ///
  /// This will be invoked in lieu of [compare] when [autoUpdateGoldenFiles]
  /// is `true` (which gets set automatically by the test framework when the
  /// user runs `flutter test --update-goldens`).
  ///
  /// The method by which [golden] is located and by which its bytes are written
  /// is left up to the implementation class.
  Future<void> update(Uri golden, Uint8List imageBytes);
}

/// Compares rasterized image bytes against a golden image file.
///
/// This comparator is used as the backend for [matchesGoldenFile].
///
/// The default comparator, [LocalFileComparator], will treat the golden key as
/// a relative path from the test file's directory. It will then load the
/// golden file's bytes from disk and perform a byte-for-byte comparison of the
/// encoded PNGs, returning true only if there's an exact match.
///
/// Callers may choose to override the default comparator by setting this to a
/// custom comparator during test set-up (or using directory-level test
/// configuration). For example, some projects may wish to install a more
/// intelligent comparator that knows how to decode the PNG images to raw
/// pixels and compare pixel vales, reporting specific differences between the
/// images.
///
/// See also:
///
///  * [flutter_test] for more information about how to configure tests at the
///    directory-level.
GoldenFileComparator get goldenFileComparator => _goldenFileComparator;
GoldenFileComparator _goldenFileComparator = const _UninitializedComparator();
set goldenFileComparator(GoldenFileComparator comparator) {
  _goldenFileComparator = comparator ?? const _UninitializedComparator();
}

/// Whether golden files should be automatically updated during tests rather
/// than compared to the image bytes recorded by the tests.
///
/// When this is `true`, [matchesGoldenFile] will always report a successful
/// match, because the bytes being tested implicitly become the new golden.
///
/// The Flutter tool will automatically set this to `true` when the user runs
/// `flutter test --update-goldens`, so callers should generally never have to
/// explicitly modify this value.
///
/// See also:
///
///   * [goldenFileComparator]
bool autoUpdateGoldenFiles = false;

/// Placeholder to signal an unexpected error in the testing framework itself.
///
/// The test harness file that gets generated by the Flutter tool when the
/// user runs `flutter test` is expected to set [goldenFileComparator] to
/// a valid comparator. From there, the caller may choose to override it by
/// setting the comparator during test initialization (e.g. in `setUpAll()`).
/// But under no circumstances do we expect it to remain uninitialized.
class _UninitializedComparator implements GoldenFileComparator {
  const _UninitializedComparator();

  @override
  Future<bool> compare(Uint8List imageBytes, Uri golden) {
    throw new StateError('goldenFileComparator has not been initialized');
  }

  @override
  Future<void> update(Uri golden, Uint8List imageBytes) {
    throw new StateError('goldenFileComparator has not been initialized');
  }
}

/// The default [GoldenFileComparator] implementation.
///
/// This comparator loads golden files from the local file system, treating the
/// golden key as a relative path from the test file's directory.
///
/// This comparator performs a very simplistic comparison, doing a byte-for-byte
/// comparison of the encoded PNGs, returning true only if there's an exact
/// match. This means it will fail the test if two PNGs represent the same
/// pixels but are encoded differently.
class LocalFileComparator implements GoldenFileComparator {
  /// Creates a new [LocalFileComparator] for the specified [testFile].
  ///
  /// Golden file keys will be interpreted as file paths relative to the
  /// directory in which [testFile] resides.
  ///
  /// The [testFile] URI must represent a file.
  LocalFileComparator(Uri testFile, {path.Style pathStyle})
      : basedir = _getBasedir(testFile, pathStyle),
        _path = _getPath(pathStyle);

  static path.Context _getPath(path.Style style) {
    return new path.Context(style: style ?? path.Style.platform);
  }

  static Uri _getBasedir(Uri testFile, path.Style pathStyle) {
    final path.Context context = _getPath(pathStyle);
    final String testFilePath = context.fromUri(testFile);
    final String testDirectoryPath = context.dirname(testFilePath);
    return context.toUri(testDirectoryPath + context.separator);
  }

  /// The directory in which the test was loaded.
  ///
  /// Golden file keys will be interpreted as file paths relative to this
  /// directory.
  final Uri basedir;

  /// Path context exists as an instance variable rather than just using the
  /// system path context in order to support testing, where we can spoof the
  /// platform to test behaviors with arbitrary path styles.
  final path.Context _path;

  @override
  Future<bool> compare(Uint8List imageBytes, Uri golden) async {
    final File goldenFile = _getFile(golden);
    if (!goldenFile.existsSync()) {
      throw new TestFailure('Could not be compared against non-existent file: "$golden"');
    }
    final List<int> goldenBytes = await goldenFile.readAsBytes();
    return _areListsEqual(imageBytes, goldenBytes);
  }

  @override
  Future<void> update(Uri golden, Uint8List imageBytes) async {
    final File goldenFile = _getFile(golden);
    await goldenFile.parent.create(recursive: true);
    await goldenFile.writeAsBytes(imageBytes, flush: true);
  }

  File _getFile(Uri golden) {
    return new File(_path.join(_path.fromUri(basedir), _path.fromUri(golden.path)));
  }

  static bool _areListsEqual<T>(List<T> list1, List<T> list2) {
    if (identical(list1, list2)) {
      return true;
    }
    if (list1 == null || list2 == null) {
      return false;
    }
    final int length = list1.length;
    if (length != list2.length) {
      return false;
    }
    for (int i = 0; i < length; i++) {
      if (list1[i] != list2[i]) {
        return false;
      }
    }
    return true;
  }
}
