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

import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/convert.dart';
import 'package:flutter_tools/src/proxied_devices/file_transfer.dart';

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

void main() {
  group('convertToChunks', () {
    test('works correctly', () async {
      final StreamController<Uint8List> controller = StreamController<Uint8List>();
      final Stream<Uint8List> chunked = convertToChunks(controller.stream, 4);
      final Future<List<Uint8List>> chunkedListFuture = chunked.toList();

      // Full chunk.
      controller.add(Uint8List.fromList(<int>[1, 2, 3, 4]));
      // Multiple of full chunks, on chunk bounraries.
      controller.add(Uint8List.fromList(<int>[5, 6, 7, 8, 9, 10, 11, 12]));
      // Larger than one chunk, starts on chunk boundary, ends not on chunk boundary.
      controller.add(Uint8List.fromList(<int>[13, 14, 15, 16, 17, 18]));
      // Larger than one chunk, starts not on chunk boundary, ends not on chunk boundary.
      controller.add(Uint8List.fromList(<int>[19, 20, 21, 22, 23]));
      // Larger than one chunk, starts not on chunk boundary, ends on chunk boundary.
      controller.add(Uint8List.fromList(<int>[24, 25, 26, 27, 28]));
      // Smaller than one chunk, starts on chunk boundary, ends not on chunk boundary.
      controller.add(Uint8List.fromList(<int>[29, 30]));
      // Smaller than one chunk, starts not on chunk boundary, ends not on chunk boundary.
      controller.add(Uint8List.fromList(<int>[31, 32, 33]));
      // Full chunk, not on chunk boundary.
      controller.add(Uint8List.fromList(<int>[34, 35, 36, 37]));
      // Smaller than one chunk, starts not on chunk boundary, ends on chunk boundary.
      controller.add(Uint8List.fromList(<int>[38, 39, 40]));
      // Empty chunk.
      controller.add(Uint8List.fromList(<int>[]));
      // Extra chunk.
      controller.add(Uint8List.fromList(<int>[41, 42]));

      await controller.close();

      final List<Uint8List> chunkedList = await chunkedListFuture;

      expect(chunkedList, hasLength(11));
      expect(chunkedList[0], <int>[1, 2, 3, 4]);
      expect(chunkedList[1], <int>[5, 6, 7, 8]);
      expect(chunkedList[2], <int>[9, 10, 11, 12]);
      expect(chunkedList[3], <int>[13, 14, 15, 16]);
      expect(chunkedList[4], <int>[17, 18, 19, 20]);
      expect(chunkedList[5], <int>[21, 22, 23, 24]);
      expect(chunkedList[6], <int>[25, 26, 27, 28]);
      expect(chunkedList[7], <int>[29, 30, 31, 32]);
      expect(chunkedList[8], <int>[33, 34, 35, 36]);
      expect(chunkedList[9], <int>[37, 38, 39, 40]);
      expect(chunkedList[10], <int>[41, 42]);
    });
  });

  group('adler32Hash', () {
    test('works correctly', () {
      final int hash = adler32Hash(utf8.encode('abcdefg'));
      expect(hash, 0x0adb02bd);
    });
  });

  group('RollingAdler32', () {
    test('works correctly without rolling', () {
      final RollingAdler32 adler32 = RollingAdler32(7);
      utf8.encode('abcdefg').forEach(adler32.push);
      expect(adler32.hash, adler32Hash(utf8.encode('abcdefg')));
    });

    test('works correctly after rolling once', () {
      final RollingAdler32 adler32 = RollingAdler32(7);
      utf8.encode('12abcdefg').forEach(adler32.push);
      expect(adler32.hash, adler32Hash(utf8.encode('abcdefg')));
    });

    test('works correctly after rolling multiple cycles', () {
      final RollingAdler32 adler32 = RollingAdler32(7);
      utf8.encode('1234567890123456789abcdefg').forEach(adler32.push);
      expect(adler32.hash, adler32Hash(utf8.encode('abcdefg')));
    });

    test('works correctly after reset', () {
      final RollingAdler32 adler32 = RollingAdler32(7);
      utf8.encode('1234567890123456789abcdefg').forEach(adler32.push);
      adler32.reset();
      utf8.encode('abcdefg').forEach(adler32.push);
      expect(adler32.hash, adler32Hash(utf8.encode('abcdefg')));
    });

    test('currentBlock returns the correct entry when read less than one block', () {
      final RollingAdler32 adler32 = RollingAdler32(7);
      utf8.encode('abcd').forEach(adler32.push);
      expect(adler32.currentBlock(), utf8.encode('abcd'));
    });

    test('currentBlock returns the correct entry when read exactly one block', () {
      final RollingAdler32 adler32 = RollingAdler32(7);
      utf8.encode('abcdefg').forEach(adler32.push);
      expect(adler32.currentBlock(), utf8.encode('abcdefg'));
    });

    test('currentBlock returns the correct entry when read more than one block', () {
      final RollingAdler32 adler32 = RollingAdler32(7);
      utf8.encode('123456789abcdefg').forEach(adler32.push);
      expect(adler32.currentBlock(), utf8.encode('abcdefg'));
    });
  });

  group('FileTransfer', () {
    const String content1 = 'a...b...c...d...e.';
    const String content2 = 'b...c...d...a...f...g...b...h..';
    const List<FileDeltaBlock> expectedDelta = <FileDeltaBlock>[
      FileDeltaBlock.fromDestination(start: 4, size: 12),
      FileDeltaBlock.fromDestination(start: 0, size: 4),
      FileDeltaBlock.fromSource(start: 16, size: 8),
      FileDeltaBlock.fromDestination(start: 4, size: 4),
      FileDeltaBlock.fromSource(start: 28, size: 3),
    ];
    const String expectedBinaryForRebuilding = 'f...g...h..';
    late MemoryFileSystem fileSystem;
    setUp(() {
      fileSystem = MemoryFileSystem();
    });

    test('calculateBlockHashesOfFile works normally', () async {
      final File file = fileSystem.file('test')..writeAsStringSync(content1);

      final BlockHashes hashes = await FileTransfer().calculateBlockHashesOfFile(file, blockSize: 4);
      expect(hashes.blockSize, 4);
      expect(hashes.totalSize, content1.length);
      expect(hashes.adler32, hasLength(5));
      expect(hashes.adler32, <int>[
        0x029c00ec,
        0x02a000ed,
        0x02a400ee,
        0x02a800ef,
        0x00fa0094,
      ]);
      expect(hashes.md5, hasLength(5));
      expect(hashes.md5, <String>[
        'zB0S8R/fGt05GcI5v8AjIQ==',
        'uZCZ4i/LUGFYAD+K1ZD0Wg==',
        '6kbZGS8T1NJl/naWODQcNw==',
        'kKh/aA2XAhR/r0HdZa3Bxg==',
        '34eF7Bs/OhfoJ5+sAw0zyw==',
      ]);
      expect(hashes.fileMd5, 'VT/gkSEdctzUEUJCxclxuQ==');
    });

    test('computeDelta returns empty list if file is identical', () async {
      final File file1 = fileSystem.file('file1')..writeAsStringSync(content1);
      final File file2 = fileSystem.file('file1')..writeAsStringSync(content1);

      final BlockHashes hashes = await FileTransfer().calculateBlockHashesOfFile(file1, blockSize: 4);
      final List<FileDeltaBlock> delta = await FileTransfer().computeDelta(file2, hashes);

      expect(delta, isEmpty);
    });

    test('computeDelta returns the correct delta', () async {
      final File file1 = fileSystem.file('file1')..writeAsStringSync(content1);
      final File file2 = fileSystem.file('file2')..writeAsStringSync(content2);

      final BlockHashes hashes = await FileTransfer().calculateBlockHashesOfFile(file1, blockSize: 4);
      final List<FileDeltaBlock> delta = await FileTransfer().computeDelta(file2, hashes);

      expect(delta, expectedDelta);
    });

    test('binaryForRebuilding returns the correct binary', () async {
      final File file = fileSystem.file('file')..writeAsStringSync(content2);
      final List<int> binaryForRebuilding = await FileTransfer().binaryForRebuilding(file, expectedDelta);
      expect(binaryForRebuilding, utf8.encode(expectedBinaryForRebuilding));
    });

    test('rebuildFile can rebuild the correct file', () async {
      final File file = fileSystem.file('file')..writeAsStringSync(content1);
      await FileTransfer().rebuildFile(file, expectedDelta, Stream<List<int>>.fromIterable(<List<int>>[utf8.encode(expectedBinaryForRebuilding)]));
      expect(file.readAsStringSync(), content2);
    });
  });
}
