// 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:convert' show json;

import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/fingerprint.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/utils.dart';

import '../../src/common.dart';
void main() {
  group('Fingerprinter', () {
    MemoryFileSystem fileSystem;

    setUp(() {
      fileSystem = MemoryFileSystem.test();
    });

    testWithoutContext('creates fingerprint with specified properties and files', () {
      fileSystem.file('a.dart').createSync();

      final Fingerprinter fingerprinter = Fingerprinter(
        fingerprintPath: 'out.fingerprint',
        paths: <String>['a.dart'],
        fileSystem: fileSystem,
        logger: BufferLogger.test(),
      );
      final Fingerprint fingerprint = fingerprinter.buildFingerprint();
      expect(fingerprint, Fingerprint.fromBuildInputs(const <String>['a.dart'], fileSystem));
    });

    testWithoutContext('creates fingerprint with file checksums', () {
      fileSystem.file('a.dart').createSync();

      final Fingerprinter fingerprinter = Fingerprinter(
        fingerprintPath: 'out.fingerprint',
        paths: <String>['a.dart'],
        fileSystem: fileSystem,
        logger: BufferLogger.test(),
      );
      final Fingerprint fingerprint = fingerprinter.buildFingerprint();
      expect(fingerprint, Fingerprint.fromBuildInputs(const <String>['a.dart'], fileSystem));
    });

    testWithoutContext('fingerprint does not match if not present', () {
      fileSystem.file('a.dart').createSync();
      fileSystem.file('b.dart').createSync();

      final Fingerprinter fingerprinter = Fingerprinter(
        fingerprintPath: 'out.fingerprint',
        paths: <String>['a.dart', 'b.dart'],
        fileSystem: fileSystem,
        logger: BufferLogger.test(),
      );
      expect(fingerprinter.doesFingerprintMatch(), isFalse);
    });
    testWithoutContext('fingerprint does match if identical', () {
      fileSystem.file('a.dart').createSync();
      fileSystem.file('b.dart').createSync();

      final Fingerprinter fingerprinter = Fingerprinter(
        fingerprintPath: 'out.fingerprint',
        paths: <String>['a.dart', 'b.dart'],
        fileSystem: fileSystem,
        logger: BufferLogger.test(),
      );
      fingerprinter.writeFingerprint();
      expect(fingerprinter.doesFingerprintMatch(), isTrue);
    });

    testWithoutContext('fails to write fingerprint if inputs are missing', () {
      final Fingerprinter fingerprinter = Fingerprinter(
        fingerprintPath: 'out.fingerprint',
        paths: <String>['a.dart'],
        fileSystem: fileSystem,
        logger: BufferLogger.test(),
      );
      fingerprinter.writeFingerprint();
      expect(fileSystem.file('out.fingerprint').existsSync(), isFalse);
    });

  group('Fingerprint', () {
    group('fromBuildInputs', () {
      MemoryFileSystem fileSystem;

      setUp(() {
        fileSystem = MemoryFileSystem.test();
      });

      testWithoutContext('throws if any input file does not exist', () {
        fileSystem.file('a.dart').createSync();
        expect(
          () => Fingerprint.fromBuildInputs(const <String>['a.dart', 'b.dart'], fileSystem),
          throwsException,
        );
      });

      testWithoutContext('populates checksums for valid files', () {
        fileSystem.file('a.dart').writeAsStringSync('This is a');
        fileSystem.file('b.dart').writeAsStringSync('This is b');
        final Fingerprint fingerprint = Fingerprint.fromBuildInputs(const <String>['a.dart', 'b.dart'], fileSystem);

        final Map<String, dynamic> jsonObject = castStringKeyedMap(json.decode(fingerprint.toJson()));
        expect(jsonObject['files'], hasLength(2));
        expect(jsonObject['files']['a.dart'], '8a21a15fad560b799f6731d436c1b698');
        expect(jsonObject['files']['b.dart'], '6f144e08b58cd0925328610fad7ac07c');
      });
    });

    group('fromJson', () {
      testWithoutContext('throws if JSON is invalid', () {
        expect(() => Fingerprint.fromJson('<xml></xml>'), throwsA(anything));
      });

      testWithoutContext('creates fingerprint from valid JSON', () {
        final String jsonString = json.encode(<String, dynamic>{
          'files': <String, dynamic>{
            'a.dart': '8a21a15fad560b799f6731d436c1b698',
            'b.dart': '6f144e08b58cd0925328610fad7ac07c',
          },
        });
        final Fingerprint fingerprint = Fingerprint.fromJson(jsonString);
        final Map<String, dynamic> content = castStringKeyedMap(json.decode(fingerprint.toJson()));
        expect(content, hasLength(1));
        expect(content['files'], hasLength(2));
        expect(content['files']['a.dart'], '8a21a15fad560b799f6731d436c1b698');
        expect(content['files']['b.dart'], '6f144e08b58cd0925328610fad7ac07c');
      });
      testWithoutContext('treats missing properties and files entries as if empty', () {
        final String jsonString = json.encode(<String, dynamic>{});
        expect(Fingerprint.fromJson(jsonString), Fingerprint.fromBuildInputs(const <String>[], fileSystem));
      });
    });

    group('operator ==', () {
      testWithoutContext('reports not equal if file checksums do not match', () {
        final Map<String, dynamic> a = <String, dynamic>{
          'files': <String, dynamic>{
            'a.dart': '8a21a15fad560b799f6731d436c1b698',
            'b.dart': '6f144e08b58cd0925328610fad7ac07c',
          },
        };
        final Map<String, dynamic> b = Map<String, dynamic>.of(a);
        b['files'] = <String, dynamic>{
          'a.dart': '8a21a15fad560b799f6731d436c1b698',
          'b.dart': '6f144e08b58cd0925328610fad7ac07d',
        };
        expect(Fingerprint.fromJson(json.encode(a)) == Fingerprint.fromJson(json.encode(b)), isFalse);
      });

      testWithoutContext('reports not equal if file paths do not match', () {
        final Map<String, dynamic> a = <String, dynamic>{
          'files': <String, dynamic>{
            'a.dart': '8a21a15fad560b799f6731d436c1b698',
            'b.dart': '6f144e08b58cd0925328610fad7ac07c',
          },
        };
        final Map<String, dynamic> b = Map<String, dynamic>.of(a);
        b['files'] = <String, dynamic>{
          'a.dart': '8a21a15fad560b799f6731d436c1b698',
          'c.dart': '6f144e08b58cd0925328610fad7ac07d',
        };
        expect(Fingerprint.fromJson(json.encode(a)) == Fingerprint.fromJson(json.encode(b)), isFalse);
      });

      testWithoutContext('reports equal if properties and file checksums match', () {
        final Map<String, dynamic> a = <String, dynamic>{
          'files': <String, dynamic>{
            'a.dart': '8a21a15fad560b799f6731d436c1b698',
            'b.dart': '6f144e08b58cd0925328610fad7ac07c',
          },
        };
        expect(Fingerprint.fromJson(json.encode(a)) == Fingerprint.fromJson(json.encode(a)), isTrue);
      });
    });
    group('hashCode', () {
      testWithoutContext('is consistent with equals, even if map entries are reordered', () {
        final Fingerprint a = Fingerprint.fromJson('{"properties":{"a":"A","b":"B"},"files":{}}');
        final Fingerprint b = Fingerprint.fromJson('{"properties":{"b":"B","a":"A"},"files":{}}');
        expect(a, b);
        expect(a.hashCode, b.hashCode);
      });
    });
  });
});
}
