// 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 'package:crypto/crypto.dart' show md5;
import 'package:meta/meta.dart';
import 'package:quiver/core.dart' show hash2;

import '../convert.dart' show json;
import '../globals.dart';
import '../version.dart';
import 'file_system.dart';
import 'platform.dart';

typedef FingerprintPathFilter = bool Function(String path);

/// Whether to completely disable build caching.
///
/// This is done by always returning false from fingerprinter invocations. This
/// is safe to do generally, because fingerprinting is only a performance
/// improvement.
bool get _disableBuildCache => platform.environment['DISABLE_FLUTTER_BUILD_CACHE']?.toLowerCase() == 'true';

/// A tool that can be used to compute, compare, and write [Fingerprint]s for a
/// set of input files and associated build settings.
///
/// This class can be used during build actions to compute a fingerprint of the
/// build action inputs and options, and if unchanged from the previous build,
/// skip the build step. This assumes that build outputs are strictly a product
/// of the fingerprint inputs.
class Fingerprinter {
  Fingerprinter({
    @required this.fingerprintPath,
    @required Iterable<String> paths,
    @required Map<String, String> properties,
    Iterable<String> depfilePaths = const <String>[],
    FingerprintPathFilter pathFilter,
  }) : _paths = paths.toList(),
       _properties = Map<String, String>.from(properties),
       _depfilePaths = depfilePaths.toList(),
       _pathFilter = pathFilter,
       assert(fingerprintPath != null),
       assert(paths != null && paths.every((String path) => path != null)),
       assert(properties != null),
       assert(depfilePaths != null && depfilePaths.every((String path) => path != null));

  final String fingerprintPath;
  final List<String> _paths;
  final Map<String, String> _properties;
  final List<String> _depfilePaths;
  final FingerprintPathFilter _pathFilter;

  Future<Fingerprint> buildFingerprint() async {
    final List<String> paths = await _getPaths();
    return Fingerprint.fromBuildInputs(_properties, paths);
  }

  Future<bool> doesFingerprintMatch() async {
    if (_disableBuildCache) {
      return false;
    }
    try {
      final File fingerprintFile = fs.file(fingerprintPath);
      if (!fingerprintFile.existsSync())
        return false;

      if (!_depfilePaths.every(fs.isFileSync))
        return false;

      final List<String> paths = await _getPaths();
      if (!paths.every(fs.isFileSync))
        return false;

      final Fingerprint oldFingerprint = Fingerprint.fromJson(await fingerprintFile.readAsString());
      final Fingerprint newFingerprint = await buildFingerprint();
      return oldFingerprint == newFingerprint;
    } catch (e) {
      // Log exception and continue, fingerprinting is only a performance improvement.
      printTrace('Fingerprint check error: $e');
    }
    return false;
  }

  Future<void> writeFingerprint() async {
    try {
      final Fingerprint fingerprint = await buildFingerprint();
      fs.file(fingerprintPath).writeAsStringSync(fingerprint.toJson());
    } catch (e) {
      // Log exception and continue, fingerprinting is only a performance improvement.
      printTrace('Fingerprint write error: $e');
    }
  }

  Future<List<String>> _getPaths() async {
    final Set<String> paths = <String>{
      ..._paths,
      for (String depfilePath in _depfilePaths)
        ...await readDepfile(depfilePath),
    };
    final FingerprintPathFilter filter = _pathFilter ?? (String path) => true;
    return paths.where(filter).toList()..sort();
  }
}

/// A fingerprint that uniquely identifies a set of build input files and
/// properties.
///
/// See [Fingerprinter].
class Fingerprint {
  Fingerprint.fromBuildInputs(Map<String, String> properties, Iterable<String> inputPaths) {
    final Iterable<File> files = inputPaths.map<File>(fs.file);
    final Iterable<File> missingInputs = files.where((File file) => !file.existsSync());
    if (missingInputs.isNotEmpty)
      throw ArgumentError('Missing input files:\n' + missingInputs.join('\n'));

    _checksums = <String, String>{};
    for (File file in files) {
      final List<int> bytes = file.readAsBytesSync();
      _checksums[file.path] = md5.convert(bytes).toString();
    }
    _properties = <String, String>{...properties};
  }

  /// Creates a Fingerprint from serialized JSON.
  ///
  /// Throws [ArgumentError], if there is a version mismatch between the
  /// serializing framework and this framework.
  Fingerprint.fromJson(String jsonData) {
    final Map<String, dynamic> content = json.decode(jsonData);

    final String version = content['version'];
    if (version != FlutterVersion.instance.frameworkRevision)
      throw ArgumentError('Incompatible fingerprint version: $version');
    _checksums = content['files']?.cast<String,String>() ?? <String, String>{};
    _properties = content['properties']?.cast<String,String>() ?? <String, String>{};
  }

  Map<String, String> _checksums;
  Map<String, String> _properties;

  String toJson() => json.encode(<String, dynamic>{
    'version': FlutterVersion.instance.frameworkRevision,
    'properties': _properties,
    'files': _checksums,
  });

  @override
  bool operator==(dynamic other) {
    if (identical(other, this))
      return true;
    if (other.runtimeType != runtimeType)
      return false;
    final Fingerprint typedOther = other;
    return _equalMaps(typedOther._checksums, _checksums)
        && _equalMaps(typedOther._properties, _properties);
  }

  bool _equalMaps(Map<String, String> a, Map<String, String> b) {
    return a.length == b.length
        && a.keys.every((String key) => a[key] == b[key]);
  }

  @override
  // Ignore map entries here to avoid becoming inconsistent with equals
  // due to differences in map entry order.
  int get hashCode => hash2(_properties.length, _checksums.length);

  @override
  String toString() => '{checksums: $_checksums, properties: $_properties}';
}

final RegExp _separatorExpr = RegExp(r'([^\\]) ');
final RegExp _escapeExpr = RegExp(r'\\(.)');

/// Parses a VM snapshot dependency file.
///
/// Snapshot dependency files are a single line mapping the output snapshot to a
/// space-separated list of input files used to generate that output. Spaces and
/// backslashes are escaped with a backslash. e.g,
///
/// outfile : file1.dart fil\\e2.dart fil\ e3.dart
///
/// will return a set containing: 'file1.dart', 'fil\e2.dart', 'fil e3.dart'.
Future<Set<String>> readDepfile(String depfilePath) async {
  // Depfile format:
  // outfile1 outfile2 : file1.dart file2.dart file3.dart
  final String contents = await fs.file(depfilePath).readAsString();

  final String dependencies = contents.split(': ')[1];
  return dependencies
      .replaceAllMapped(_separatorExpr, (Match match) => '${match.group(1)}\n')
      .split('\n')
      .map<String>((String path) => path.replaceAllMapped(_escapeExpr, (Match match) => match.group(1)).trim())
      .where((String path) => path.isNotEmpty)
      .toSet();
}


