// 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/file_system.dart';
import 'package:flutter_tools/src/base/fingerprint.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/utils.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/version.dart';
import 'package:mockito/mockito.dart';

import '../../src/common.dart';
import '../../src/context.dart';

void main() {
  group('Fingerprinter', () {
    const String kVersion = '123456abcdef';

    MemoryFileSystem fs;
    MockFlutterVersion mockVersion;

    setUp(() {
      fs = MemoryFileSystem();
      mockVersion = MockFlutterVersion();
      when(mockVersion.frameworkRevision).thenReturn(kVersion);
    });

    final Map<Type, Generator> contextOverrides = <Type, Generator>{
      FileSystem: () => fs,
      ProcessManager: () => FakeProcessManager.any(),
    };

    testUsingContext('throws when depfile is malformed', () {
      globals.fs.file('a.dart').createSync();
      globals.fs.file('b.dart').createSync();
      globals.fs.file('depfile').createSync();

      final Fingerprinter fingerprinter = Fingerprinter(
        fingerprintPath: 'out.fingerprint',
        paths: <String>['a.dart'],
        depfilePaths: <String>['depfile'],
        properties: <String, String>{
          'bar': 'baz',
          'wobble': 'womble',
        },
      );
      expect(() => fingerprinter.buildFingerprint(), throwsA(anything));
    }, overrides: contextOverrides);

    testUsingContext('creates fingerprint with specified properties and files', () {
      globals.fs.file('a.dart').createSync();

      final Fingerprinter fingerprinter = Fingerprinter(
        fingerprintPath: 'out.fingerprint',
        paths: <String>['a.dart'],
        properties: <String, String>{
          'foo': 'bar',
          'wibble': 'wobble',
        },
      );
      final Fingerprint fingerprint = fingerprinter.buildFingerprint();
      expect(fingerprint, Fingerprint.fromBuildInputs(const <String, String>{
        'foo': 'bar',
        'wibble': 'wobble',
      }, const <String>['a.dart']));
    }, overrides: contextOverrides);

    testUsingContext('creates fingerprint with file checksums', () {
      globals.fs.file('a.dart').createSync();
      globals.fs.file('b.dart').createSync();
      globals.fs.file('depfile').writeAsStringSync('depfile : b.dart');

      final Fingerprinter fingerprinter = Fingerprinter(
        fingerprintPath: 'out.fingerprint',
        paths: <String>['a.dart'],
        depfilePaths: <String>['depfile'],
        properties: <String, String>{
          'bar': 'baz',
          'wobble': 'womble',
        },
      );
      final Fingerprint fingerprint = fingerprinter.buildFingerprint();
      expect(fingerprint, Fingerprint.fromBuildInputs(const <String, String>{
        'bar': 'baz',
        'wobble': 'womble',
      }, const <String>['a.dart', 'b.dart']));
    }, overrides: contextOverrides);

    testUsingContext('fingerprint does not match if not present', () {
      globals.fs.file('a.dart').createSync();
      globals.fs.file('b.dart').createSync();

      final Fingerprinter fingerprinter = Fingerprinter(
        fingerprintPath: 'out.fingerprint',
        paths: <String>['a.dart', 'b.dart'],
        properties: <String, String>{
          'bar': 'baz',
          'wobble': 'womble',
        },
      );
      expect(fingerprinter.doesFingerprintMatch(), isFalse);
    }, overrides: contextOverrides);

    testUsingContext('fingerprint does match if different', () {
      globals.fs.file('a.dart').createSync();
      globals.fs.file('b.dart').createSync();

      final Fingerprinter fingerprinter1 = Fingerprinter(
        fingerprintPath: 'out.fingerprint',
        paths: <String>['a.dart', 'b.dart'],
        properties: <String, String>{
          'bar': 'baz',
          'wobble': 'womble',
        },
      );
      fingerprinter1.writeFingerprint();

      final Fingerprinter fingerprinter2 = Fingerprinter(
        fingerprintPath: 'out.fingerprint',
        paths: <String>['a.dart', 'b.dart'],
        properties: <String, String>{
          'bar': 'baz',
          'wobble': 'elbmow',
        },
      );
      expect(fingerprinter2.doesFingerprintMatch(), isFalse);
    }, overrides: contextOverrides);

    testUsingContext('fingerprint does not match if depfile is malformed', () {
      globals.fs.file('a.dart').createSync();
      globals.fs.file('b.dart').createSync();
      globals.fs.file('depfile').writeAsStringSync('depfile : b.dart');

      // Write a valid fingerprint
      final Fingerprinter fingerprinter = Fingerprinter(
        fingerprintPath: 'out.fingerprint',
        paths: <String>['a.dart', 'b.dart'],
        depfilePaths: <String>['depfile'],
        properties: <String, String>{
          'bar': 'baz',
          'wobble': 'womble',
        },
      );
      fingerprinter.writeFingerprint();

      // Write a corrupt depfile.
      globals.fs.file('depfile').writeAsStringSync('');
      final Fingerprinter badFingerprinter = Fingerprinter(
        fingerprintPath: 'out.fingerprint',
        paths: <String>['a.dart', 'b.dart'],
        depfilePaths: <String>['depfile'],
        properties: <String, String>{
          'bar': 'baz',
          'wobble': 'womble',
        },
      );

      expect(badFingerprinter.doesFingerprintMatch(), isFalse);
    }, overrides: contextOverrides);

    testUsingContext('fingerprint does not match if previous fingerprint is malformed', () {
      globals.fs.file('a.dart').createSync();
      globals.fs.file('b.dart').createSync();
      globals.fs.file('out.fingerprint').writeAsStringSync('** not JSON **');

      final Fingerprinter fingerprinter = Fingerprinter(
        fingerprintPath: 'out.fingerprint',
        paths: <String>['a.dart', 'b.dart'],
        depfilePaths: <String>['depfile'],
        properties: <String, String>{
          'bar': 'baz',
          'wobble': 'womble',
        },
      );
      expect(fingerprinter.doesFingerprintMatch(), isFalse);
    }, overrides: contextOverrides);

    testUsingContext('fingerprint does match if identical', () {
      globals.fs.file('a.dart').createSync();
      globals.fs.file('b.dart').createSync();

      final Fingerprinter fingerprinter = Fingerprinter(
        fingerprintPath: 'out.fingerprint',
        paths: <String>['a.dart', 'b.dart'],
        properties: <String, String>{
          'bar': 'baz',
          'wobble': 'womble',
        },
      );
      fingerprinter.writeFingerprint();
      expect(fingerprinter.doesFingerprintMatch(), isTrue);
    }, overrides: contextOverrides);

    testUsingContext('fails to write fingerprint if inputs are missing', () {
      final Fingerprinter fingerprinter = Fingerprinter(
        fingerprintPath: 'out.fingerprint',
        paths: <String>['a.dart'],
        properties: <String, String>{
          'foo': 'bar',
          'wibble': 'wobble',
        },
      );
      fingerprinter.writeFingerprint();
      expect(globals.fs.file('out.fingerprint').existsSync(), isFalse);
    }, overrides: contextOverrides);

    testUsingContext('applies path filter to inputs paths', () {
      globals.fs.file('a.dart').createSync();
      globals.fs.file('ab.dart').createSync();
      globals.fs.file('depfile').writeAsStringSync('depfile : ab.dart c.dart');

      final Fingerprinter fingerprinter = Fingerprinter(
        fingerprintPath: 'out.fingerprint',
        paths: <String>['a.dart'],
        depfilePaths: <String>['depfile'],
        properties: <String, String>{
          'foo': 'bar',
          'wibble': 'wobble',
        },
        pathFilter: (String path) => path.startsWith('a'),
      );
      fingerprinter.writeFingerprint();
      expect(globals.fs.file('out.fingerprint').existsSync(), isTrue);
    }, overrides: contextOverrides);
  });

  group('Fingerprint', () {
    MockFlutterVersion mockVersion;
    const String kVersion = '123456abcdef';

    setUp(() {
      mockVersion = MockFlutterVersion();
      when(mockVersion.frameworkRevision).thenReturn(kVersion);
    });

    group('fromBuildInputs', () {
      MemoryFileSystem fs;

      setUp(() {
        fs = MemoryFileSystem();
      });

      testUsingContext('throws if any input file does not exist', () {
        globals.fs.file('a.dart').createSync();
        expect(
          () => Fingerprint.fromBuildInputs(const <String, String>{}, const <String>['a.dart', 'b.dart']),
          throwsException,
        );
      }, overrides: <Type, Generator>{
        FileSystem: () => fs,
        ProcessManager: () => FakeProcessManager.any(),
      });

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

        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');
      }, overrides: <Type, Generator>{
        FileSystem: () => fs,
        ProcessManager: () => FakeProcessManager.any(),
      });

      testUsingContext('includes framework version', () {
        final Fingerprint fingerprint = Fingerprint.fromBuildInputs(const <String, String>{}, const <String>[]);

        final Map<String, dynamic> jsonObject = castStringKeyedMap(json.decode(fingerprint.toJson()));
        expect(jsonObject['version'], mockVersion.frameworkRevision);
      }, overrides: <Type, Generator>{FlutterVersion: () => mockVersion});

      testUsingContext('includes provided properties', () {
        final Fingerprint fingerprint = Fingerprint.fromBuildInputs(const <String, String>{'a': 'A', 'b': 'B'}, const <String>[]);

        final Map<String, dynamic> jsonObject = castStringKeyedMap(json.decode(fingerprint.toJson()));
        expect(jsonObject['properties'], hasLength(2));
        expect(jsonObject['properties']['a'], 'A');
        expect(jsonObject['properties']['b'], 'B');
      }, overrides: <Type, Generator>{FlutterVersion: () => mockVersion});
    });

    group('fromJson', () {
      testUsingContext('throws if JSON is invalid', () {
        expect(() => Fingerprint.fromJson('<xml></xml>'), throwsA(anything));
      }, overrides: <Type, Generator>{
        FlutterVersion: () => mockVersion,
      });

      testUsingContext('creates fingerprint from valid JSON', () {
        final String jsonString = json.encode(<String, dynamic>{
          'version': kVersion,
          'properties': <String, String>{
            'buildMode': BuildMode.release.toString(),
            'targetPlatform': TargetPlatform.ios.toString(),
            'entryPoint': 'a.dart',
          },
          '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(3));
        expect(content['version'], mockVersion.frameworkRevision);
        expect(content['properties'], hasLength(3));
        expect(content['properties']['buildMode'], BuildMode.release.toString());
        expect(content['properties']['targetPlatform'], TargetPlatform.ios.toString());
        expect(content['properties']['entryPoint'], 'a.dart');
        expect(content['files'], hasLength(2));
        expect(content['files']['a.dart'], '8a21a15fad560b799f6731d436c1b698');
        expect(content['files']['b.dart'], '6f144e08b58cd0925328610fad7ac07c');
      }, overrides: <Type, Generator>{
        FlutterVersion: () => mockVersion,
      });

      testUsingContext('throws ArgumentError for unknown versions', () {
        final String jsonString = json.encode(<String, dynamic>{
          'version': 'bad',
          'properties': <String, String>{},
          'files': <String, String>{},
        });
        expect(() => Fingerprint.fromJson(jsonString), throwsException);
      }, overrides: <Type, Generator>{
        FlutterVersion: () => mockVersion,
      });

      testUsingContext('throws ArgumentError if version is not present', () {
        final String jsonString = json.encode(<String, dynamic>{
          'properties': <String, String>{},
          'files': <String, String>{},
        });
        expect(() => Fingerprint.fromJson(jsonString), throwsException);
      }, overrides: <Type, Generator>{
        FlutterVersion: () => mockVersion,
      });

      testUsingContext('treats missing properties and files entries as if empty', () {
        final String jsonString = json.encode(<String, dynamic>{
          'version': kVersion,
        });
        expect(Fingerprint.fromJson(jsonString), Fingerprint.fromBuildInputs(const <String, String>{}, const <String>[]));
      }, overrides: <Type, Generator>{
        FlutterVersion: () => mockVersion,
      });
    });

    group('operator ==', () {
      testUsingContext('reports not equal if properties do not match', () {
        final Map<String, dynamic> a = <String, dynamic>{
          'version': kVersion,
          'properties': <String, String>{
            'buildMode': BuildMode.debug.toString(),
          },
          'files': <String, dynamic>{},
        };
        final Map<String, dynamic> b = Map<String, dynamic>.of(a);
        b['properties'] = <String, String>{
          'buildMode': BuildMode.release.toString(),
        };
        expect(Fingerprint.fromJson(json.encode(a)) == Fingerprint.fromJson(json.encode(b)), isFalse);
      }, overrides: <Type, Generator>{
        FlutterVersion: () => mockVersion,
      });

      testUsingContext('reports not equal if file checksums do not match', () {
        final Map<String, dynamic> a = <String, dynamic>{
          'version': kVersion,
          'properties': <String, String>{},
          '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);
      }, overrides: <Type, Generator>{
        FlutterVersion: () => mockVersion,
      });

      testUsingContext('reports not equal if file paths do not match', () {
        final Map<String, dynamic> a = <String, dynamic>{
          'version': kVersion,
          'properties': <String, String>{},
          '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);
      }, overrides: <Type, Generator>{
        FlutterVersion: () => mockVersion,
      });

      testUsingContext('reports equal if properties and file checksums match', () {
        final Map<String, dynamic> a = <String, dynamic>{
          'version': kVersion,
          'properties': <String, String>{
            'buildMode': BuildMode.debug.toString(),
            'targetPlatform': TargetPlatform.ios.toString(),
            'entryPoint': 'a.dart',
          },
          'files': <String, dynamic>{
            'a.dart': '8a21a15fad560b799f6731d436c1b698',
            'b.dart': '6f144e08b58cd0925328610fad7ac07c',
          },
        };
        expect(Fingerprint.fromJson(json.encode(a)) == Fingerprint.fromJson(json.encode(a)), isTrue);
      }, overrides: <Type, Generator>{
        FlutterVersion: () => mockVersion,
      });
    });
    group('hashCode', () {
      testUsingContext('is consistent with equals, even if map entries are reordered', () {
        final Fingerprint a = Fingerprint.fromJson('{"version":"$kVersion","properties":{"a":"A","b":"B"},"files":{}}');
        final Fingerprint b = Fingerprint.fromJson('{"version":"$kVersion","properties":{"b":"B","a":"A"},"files":{}}');
        expect(a, b);
        expect(a.hashCode, b.hashCode);
      }, overrides: <Type, Generator>{
        FlutterVersion: () => mockVersion,
      });

    });
  });

  group('readDepfile', () {
    MemoryFileSystem fs;

    setUp(() {
      fs = MemoryFileSystem();
    });

    final Map<Type, Generator> contextOverrides = <Type, Generator>{
      FileSystem: () => fs,
      ProcessManager: () => FakeProcessManager.any(),
    };

    testUsingContext('returns one file if only one is listed', () {
      globals.fs.file('a.d').writeAsStringSync('snapshot.d: /foo/a.dart');
      expect(readDepfile('a.d'), unorderedEquals(<String>['/foo/a.dart']));
    }, overrides: contextOverrides);

    testUsingContext('returns multiple files', () {
      globals.fs.file('a.d').writeAsStringSync('snapshot.d: /foo/a.dart /foo/b.dart');
      expect(readDepfile('a.d'), unorderedEquals(<String>[
        '/foo/a.dart',
        '/foo/b.dart',
      ]));
    }, overrides: contextOverrides);

    testUsingContext('trims extra spaces between files', () {
      globals.fs.file('a.d').writeAsStringSync('snapshot.d: /foo/a.dart    /foo/b.dart  /foo/c.dart');
      expect(readDepfile('a.d'), unorderedEquals(<String>[
        '/foo/a.dart',
        '/foo/b.dart',
        '/foo/c.dart',
      ]));
    }, overrides: contextOverrides);

    testUsingContext('returns files with spaces and backslashes', () {
      globals.fs.file('a.d').writeAsStringSync(r'snapshot.d: /foo/a\ a.dart /foo/b\\b.dart /foo/c\\ c.dart');
      expect(readDepfile('a.d'), unorderedEquals(<String>[
        r'/foo/a a.dart',
        r'/foo/b\b.dart',
        r'/foo/c\ c.dart',
      ]));
    }, overrides: contextOverrides);
  });
}

class MockPlatform extends Mock implements Platform {
  @override
  Map<String, String> environment = <String, String>{};
}
