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

import 'package:cocoon_service/src/service/cache_service.dart';
import 'package:mockito/mockito.dart';
import 'package:neat_cache/neat_cache.dart';
import 'package:test/test.dart';

import '../src/utilities/mocks.dart';

void main() {
  group('CacheService', () {
    late CacheService cache;

    const String testSubcacheName = 'test';

    setUp(() {
      cache = CacheService(inMemory: true, inMemoryMaxNumberEntries: 1);
    });

    test('returns null when no value exists', () async {
      final Uint8List? value = await cache.getOrCreate(testSubcacheName, 'abc');

      expect(value, isNull);
    });

    test('returns value when it exists', () async {
      const String testKey = 'abc';
      final Uint8List expectedValue = Uint8List.fromList('123'.codeUnits);

      await cache.set(testSubcacheName, testKey, expectedValue);

      final Uint8List? value = await cache.getOrCreate(testSubcacheName, testKey);

      expect(value, expectedValue);
    });

    test('last used value is rotated out of cache if cache is full', () async {
      const String testKey1 = 'abc';
      const String testKey2 = 'def';
      final Uint8List expectedValue1 = Uint8List.fromList('123'.codeUnits);
      final Uint8List expectedValue2 = Uint8List.fromList('456'.codeUnits);

      await cache.set(testSubcacheName, testKey1, expectedValue1);
      await cache.set(testSubcacheName, testKey2, expectedValue2);

      final Uint8List? value1 = await cache.getOrCreate(testSubcacheName, testKey1);
      expect(value1, null);

      final Uint8List? value2 = await cache.getOrCreate(testSubcacheName, testKey2);
      expect(value2, expectedValue2);
    });

    test('retries when get throws exception', () async {
      final Cache<Uint8List> mockMainCache = MockCache();
      final Cache<Uint8List> mockTestSubcache = MockCache();
      when<Cache<Uint8List>>(mockMainCache.withPrefix(testSubcacheName)).thenReturn(mockTestSubcache);

      int getCallCount = 0;
      final Entry<Uint8List> entry = FakeEntry();
      // Only on the first call do we want it to throw the exception.
      when(mockTestSubcache['does not matter']).thenAnswer(
          (Invocation invocation) => getCallCount++ < 1 ? throw Exception('simulate stream sink error') : entry);

      cache.cacheValue = mockMainCache;

      final Uint8List? value = await cache.getOrCreate(testSubcacheName, 'does not matter');
      verify(mockTestSubcache['does not matter']).called(2);
      expect(value, Uint8List.fromList('abc123'.codeUnits));
    });

    test('returns null if reaches max attempts of retries', () async {
      final Cache<Uint8List> mockMainCache = MockCache();
      final Cache<Uint8List> mockTestSubcache = MockCache();
      when<Cache<Uint8List>>(mockMainCache.withPrefix(testSubcacheName)).thenReturn(mockTestSubcache);

      int getCallCount = 0;
      final Entry<Uint8List> entry = FakeEntry();
      // Always throw exception until max retries
      when(mockTestSubcache['does not matter']).thenAnswer((Invocation invocation) =>
          getCallCount++ < CacheService.maxCacheGetAttempts ? throw Exception('simulate stream sink error') : entry);

      cache.cacheValue = mockMainCache;

      final Uint8List? value = await cache.getOrCreate(testSubcacheName, 'does not matter');
      verify(mockTestSubcache['does not matter']).called(CacheService.maxCacheGetAttempts);
      expect(value, isNull);
    });

    test('creates value if given createFn', () async {
      final Uint8List cat = Uint8List.fromList('cat'.codeUnits);
      Future<Uint8List> createCat() async => cat;

      final Uint8List? value = await cache.getOrCreate(testSubcacheName, 'dog', createFn: createCat);

      expect(value, cat);
    });

    test('purge removes value', () async {
      const String testKey = 'abc';
      final Uint8List expectedValue = Uint8List.fromList('123'.codeUnits);

      await cache.set(testSubcacheName, testKey, expectedValue);

      final Uint8List? value = await cache.getOrCreate(testSubcacheName, testKey);

      expect(value, expectedValue);

      await cache.purge(testSubcacheName, testKey);

      final Uint8List? valueAfterPurge = await cache.getOrCreate(testSubcacheName, testKey);
      expect(valueAfterPurge, isNull);
    });

    test('sets ttl from set', () async {
      final Cache<Uint8List> mockMainCache = MockCache();
      final Cache<Uint8List> mockTestSubcache = MockCache();
      when<Cache<Uint8List>>(mockMainCache.withPrefix(testSubcacheName)).thenReturn(mockTestSubcache);

      final Entry<Uint8List> entry = MockFakeEntry();
      when(mockTestSubcache['fish']).thenAnswer((Invocation invocation) => entry);
      cache.cacheValue = mockMainCache;

      const Duration testDuration = Duration(days: 40);
      when(entry.set(any, testDuration)).thenAnswer((_) async => null);
      verifyNever(entry.set(any, testDuration));
      await cache.set(testSubcacheName, 'fish', Uint8List.fromList('bigger fish'.codeUnits), ttl: testDuration);
      verify(entry.set(any, testDuration)).called(1);
    });

    test('sets ttl is passed through correctly from createFn', () async {
      const String value = 'bigger fish';
      final Uint8List valueBytes = Uint8List.fromList(value.codeUnits);
      const Duration testDuration = Duration(days: 40);

      final Entry<Uint8List> entry = MockFakeEntry();
      when(entry.set(valueBytes, testDuration)).thenAnswer((_) async => valueBytes);

      final Cache<Uint8List> mockTestSubcache = MockCache();
      final Cache<Uint8List> mockMainCache = MockCache();
      when<Cache<Uint8List>>(mockMainCache.withPrefix(testSubcacheName)).thenReturn(mockTestSubcache);
      when(mockTestSubcache['fish']).thenAnswer((Invocation invocation) => entry);
      cache.cacheValue = mockMainCache;

      verifyNever(entry.set(any, testDuration));
      await cache.getOrCreate(
        testSubcacheName,
        'fish',
        createFn: () async => valueBytes,
        ttl: testDuration,
      );
      verify(entry.set(any, testDuration)).called(1);
    });
  });
}

class FakeEntry extends Entry<Uint8List> {
  Uint8List value = Uint8List.fromList('abc123'.codeUnits);

  @override
  Future<Uint8List> get([Future<Uint8List?> Function()? create, Duration? ttl]) async => value;

  @override
  Future<void> purge({int retries = 0}) => throw UnimplementedError();

  @override
  Future<Uint8List?> set(Uint8List? value, [Duration? ttl]) async {
    value = value;

    return value;
  }
}
