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

import 'package:file/file.dart';
import 'package:file/local.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:meta/meta.dart';
import 'package:platform/platform.dart';

import 'package:flutter_goldens_client/client.dart';
import 'package:flutter_goldens_client/skia_client.dart';

export 'package:flutter_goldens_client/client.dart';
export 'package:flutter_goldens_client/skia_client.dart';

/// Main method that can be used in a `flutter_test_config.dart` file to set
/// [goldenFileComparator] to an instance of [FlutterGoldenFileComparator] that
/// works for the current test. _Which_ FlutterGoldenFileComparator is
/// instantiated is based on the current testing environment.
Future<void> main(FutureOr<void> testMain()) async {
  const Platform platform = LocalPlatform();
  if (FlutterSkiaGoldFileComparator.isAvailableOnPlatform(platform)) {
    goldenFileComparator = await FlutterSkiaGoldFileComparator.fromDefaultComparator();
  } else if (FlutterGoldensRepositoryFileComparator.isAvailableOnPlatform(platform)) {
    goldenFileComparator = await FlutterGoldensRepositoryFileComparator.fromDefaultComparator();
  } else {
    goldenFileComparator = FlutterSkippingGoldenFileComparator.fromDefaultComparator();
  }
  await testMain();
}

/// Abstract base class golden file comparator specific to the `flutter/flutter`
/// repository.
abstract class FlutterGoldenFileComparator extends GoldenFileComparator {
  /// Creates a [FlutterGoldenFileComparator] that will resolve golden file
  /// URIs relative to the specified [basedir].
  ///
  /// The [fs] and [platform] parameters useful in tests, where the default file
  /// system and platform can be replaced by mock instances.
  @visibleForTesting
  FlutterGoldenFileComparator(
    this.basedir, {
    this.fs = const LocalFileSystem(),
    this.platform = const LocalPlatform(),
  }) : assert(basedir != null),
       assert(fs != null),
       assert(platform != null);

  /// The directory to which golden file URIs will be resolved in [compare] and
  /// [update].
  final Uri basedir;

  /// The file system used to perform file access.
  @visibleForTesting
  final FileSystem fs;

  /// A wrapper for the [dart:io.Platform] API.
  @visibleForTesting
  final Platform platform;

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

  /// Calculate the appropriate basedir for the current test context.
  @protected
  @visibleForTesting
  static Directory getBaseDirectory(GoldensClient goldens, LocalFileComparator defaultComparator) {
    final FileSystem fs = goldens.fs;
    final Directory testDirectory = fs.directory(defaultComparator.basedir);
    final String testDirectoryRelativePath = fs.path.relative(testDirectory.path, from: goldens.flutterRoot.path);
    return goldens.comparisonRoot.childDirectory(testDirectoryRelativePath);
  }

  /// Returns the golden [File] identified by the given [Uri].
  @protected
  File getGoldenFile(Uri uri) {
    assert(basedir.scheme == 'file');
    final File goldenFile = fs.directory(basedir).childFile(fs.file(uri).path);
    assert(goldenFile.uri.scheme == 'file');
    return goldenFile;
  }
}

/// A [FlutterGoldenFileComparator] for testing golden images against the
/// `flutter/goldens` repository.
///
/// Within the https://github.com/flutter/flutter repository, it's important
/// not to check-in binaries in order to keep the size of the repository to a
/// minimum. To satisfy this requirement, this comparator retrieves the golden
/// files from a sibling repository, `flutter/goldens`.
///
/// This comparator will locally clone the `flutter/goldens` repository into
/// the `$FLUTTER_ROOT/bin/cache/pkg/goldens` folder using the
/// [GoldensRepositoryClient], then perform the comparison against the files
/// therein.
///
/// See also:
///
///  * [GoldenFileComparator], the abstract class that
///    [FlutterGoldenFileComparator] implements.
///  * [FlutterSkiaGoldFileComparator], another [FlutterGoldenFileComparator]
///    that tests golden images through Skia Gold.
class FlutterGoldensRepositoryFileComparator extends FlutterGoldenFileComparator {
  /// Creates a [FlutterGoldensRepositoryFileComparator] that will test golden
  /// file images against the `flutter/goldens` repository.
  ///
  /// The [fs] and [platform] parameters useful in tests, where the default file
  /// system and platform can be replaced by mock instances.
  FlutterGoldensRepositoryFileComparator(
    Uri basedir, {
    FileSystem fs = const LocalFileSystem(),
    Platform platform = const LocalPlatform(),
  }) : super(
    basedir,
    fs: fs,
    platform: platform,
  );

  /// Creates a new [FlutterGoldensRespositoryFileComparator] that mirrors the
  /// relative path resolution of the default [goldenFileComparator].
  ///
  /// By the time the future completes, the clone of the `flutter/goldens`
  /// repository is guaranteed to be ready to use.
  ///
  /// The [goldens] and [defaultComparator] parameters are visible for testing
  /// purposes only.
  static Future<FlutterGoldensRepositoryFileComparator> fromDefaultComparator({
    GoldensRepositoryClient goldens,
    LocalFileComparator defaultComparator,
  }) async {
    defaultComparator ??= goldenFileComparator;

    // Prepare the goldens repo.
    goldens ??= GoldensRepositoryClient();
    await goldens.prepare();

    final Directory baseDirectory = FlutterGoldenFileComparator.getBaseDirectory(goldens, defaultComparator);
    return FlutterGoldensRepositoryFileComparator(baseDirectory.uri);
  }

  @override
  Future<bool> compare(Uint8List imageBytes, Uri golden) async {
    final File goldenFile = getGoldenFile(golden);
    if (!goldenFile.existsSync()) {
      throw TestFailure('Could not be compared against non-existent file: "$golden"');
    }
    final List<int> goldenBytes = await goldenFile.readAsBytes();
    if (goldenBytes.length != imageBytes.length) {
      return false;
    }
    for (int i = 0; i < goldenBytes.length; i++) {
      if (goldenBytes[i] != imageBytes[i]) {
        return false;
      }
    }
    return true;
  }

  /// Decides based on the current platform whether goldens tests should be
  /// performed against the flutter/goldens repository.
  static bool isAvailableOnPlatform(Platform platform) => platform.isLinux;
}

/// A [FlutterGoldenFileComparator] for testing golden images with Skia Gold.
///
/// For testing across all platforms, the [SkiaGoldClient] is used to upload
/// images for framework-related golden tests and process results. Currently
/// these tests are designed to be run post-submit on Cirrus CI, informed by the
/// environment.
///
/// See also:
///
///  * [GoldenFileComparator], the abstract class that
///    [FlutterGoldenFileComparator] implements.
///  * [FlutterGoldensRepositoryFileComparator], another
///    [FlutterGoldenFileComparator] that tests golden images using the
///    flutter/goldens repository.
class FlutterSkiaGoldFileComparator extends FlutterGoldenFileComparator {
  /// Creates a [FlutterSkiaGoldFileComparator] that will test golden file
  /// images against Skia Gold.
  ///
  /// The [fs] and [platform] parameters useful in tests, where the default file
  /// system and platform can be replaced by mock instances.
  FlutterSkiaGoldFileComparator(
    final Uri basedir,
    this.skiaClient, {
    FileSystem fs = const LocalFileSystem(),
    Platform platform = const LocalPlatform(),
  }) : super(
    basedir,
    fs: fs,
    platform: platform,
  );

  final SkiaGoldClient skiaClient;

  /// Creates a new [FlutterSkiaGoldFileComparator] that mirrors the relative
  /// path resolution of the default [goldenFileComparator].
  ///
  /// The [goldens] and [defaultComparator] parameters are visible for testing
  /// purposes only.
  static Future<FlutterSkiaGoldFileComparator> fromDefaultComparator({
    SkiaGoldClient goldens,
    LocalFileComparator defaultComparator,
  }) async {
    defaultComparator ??= goldenFileComparator;
    goldens ??= SkiaGoldClient();

    final Directory baseDirectory = FlutterGoldenFileComparator.getBaseDirectory(goldens, defaultComparator);
    if (!baseDirectory.existsSync())
      baseDirectory.createSync(recursive: true);
    await goldens.auth(baseDirectory);
    await goldens.imgtestInit();
    return FlutterSkiaGoldFileComparator(baseDirectory.uri, goldens);
  }

  @override
  Future<bool> compare(Uint8List imageBytes, Uri golden) async {
    golden = _addPrefix(golden);
    await update(golden, imageBytes);

    final File goldenFile = getGoldenFile(golden);
    if (!goldenFile.existsSync()) {
      throw TestFailure('Could not be compared against non-existent file: "$golden"');
    }
    return await skiaClient.imgtestAdd(golden.path, goldenFile);
  }

  @override
  Uri getTestUri(Uri key, int version) => key;

  /// Decides based on the current environment whether goldens tests should be
  /// performed against Skia Gold.
  static bool isAvailableOnPlatform(Platform platform) {
    final String cirrusCI = platform.environment['CIRRUS_CI'] ?? '';
    final String cirrusPR = platform.environment['CIRRUS_PR'] ?? '';
    final String cirrusBranch = platform.environment['CIRRUS_BRANCH'] ?? '';
    final String goldServiceAccount = platform.environment['GOLD_SERVICE_ACCOUNT'] ?? '';
    return cirrusCI.isNotEmpty
      && cirrusPR.isEmpty
      && cirrusBranch == 'master'
      && goldServiceAccount.isNotEmpty;
  }

  /// Prepends the golden Uri with the library name that encloses the current
  /// test.
  Uri _addPrefix(Uri golden) {
    final String prefix = basedir.pathSegments[basedir.pathSegments.length - 2];
    return Uri.parse(prefix + '.' + golden.toString());
  }
}

/// A [FlutterGoldenFileComparator] for skipping golden image tests when Skia
/// Gold is unavailable or the current platform that is executing tests is not
/// Linux.
///
/// See also:
///
///  * [FlutterGoldensRepositoryFileComparator], another
///    [FlutterGoldenFileComparator] that tests golden images using the
///    flutter/goldens repository.
///  * [FlutterSkiaGoldFileComparator], another [FlutterGoldenFileComparator]
///    that tests golden images through Skia Gold.
class FlutterSkippingGoldenFileComparator extends FlutterGoldenFileComparator {
  /// Creates a [FlutterSkippingGoldenFileComparator] that will skip tests that
  /// are not in the right environment for golden file testing.
  FlutterSkippingGoldenFileComparator(Uri basedir) : super(basedir);

  /// Creates a new [FlutterSkippingGoldenFileComparator] that mirrors the relative
  /// path resolution of the default [goldenFileComparator].
  static FlutterSkippingGoldenFileComparator fromDefaultComparator({
    LocalFileComparator defaultComparator,
  }) {
    defaultComparator ??= goldenFileComparator;
    return FlutterSkippingGoldenFileComparator(defaultComparator.basedir);
  }

  @override
  Future<bool> compare(Uint8List imageBytes, Uri golden) async {
    print('Skipping "$golden" test : Skia Gold is not available in this testing '
      'environment and flutter/goldens repository comparison is only available '
      'on Linux machines.'
    );
    return true;
  }

  @override
  Future<void> update(Uri golden, Uint8List imageBytes) => null;
}
