// Copyright 2013 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 'package:js/js.dart';

import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';

import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart';

import '../matchers.dart';
import '../spy.dart';
import 'common.dart';

void main() {
  internalBootstrapBrowserTest(() => testMain);
}

void testMain() {
  group('skia_objects_cache', () {
    _tests();
  });
}

void _tests() {
  SkiaObjects.maximumCacheSize = 4;

  setUpCanvasKitTest();

  setUp(() async {
    // Pretend the browser does not support FinalizationRegistry so we can test the
    // resurrection logic.
    browserSupportsFinalizationRegistry = false;
  });

  group(ManagedSkiaObject, () {
    test('implements create, cache, delete, resurrect, delete lifecycle', () {
      final FakeRasterizer fakeRasterizer = FakeRasterizer();
      CanvasKitRenderer.instance.rasterizer = fakeRasterizer;

      // Trigger first create
      final TestSkiaObject testObject = TestSkiaObject();
      expect(SkiaObjects.resurrectableObjects.single, testObject);
      expect(testObject.createDefaultCount, 1);
      expect(testObject.resurrectCount, 0);
      expect(testObject.deleteCount, 0);

      // Check that the getter does not have side-effects
      final SkPaint skiaObject1 = testObject.skiaObject;
      expect(skiaObject1, isNotNull);
      expect(SkiaObjects.resurrectableObjects.single, testObject);
      expect(testObject.createDefaultCount, 1);
      expect(testObject.resurrectCount, 0);
      expect(testObject.deleteCount, 0);

      // Trigger first delete
      SkiaObjects.postFrameCleanUp();
      expect(SkiaObjects.resurrectableObjects, isEmpty);
      expect(fakeRasterizer.addPostFrameCallbackCount, 1);
      expect(testObject.createDefaultCount, 1);
      expect(testObject.resurrectCount, 0);
      expect(testObject.deleteCount, 1);

      // Trigger resurrect
      final SkPaint skiaObject2 = testObject.skiaObject;
      expect(skiaObject2, isNotNull);
      expect(skiaObject2, isNot(same(skiaObject1)));
      expect(SkiaObjects.resurrectableObjects.single, testObject);
      expect(fakeRasterizer.addPostFrameCallbackCount, 1);
      expect(testObject.createDefaultCount, 1);
      expect(testObject.resurrectCount, 1);
      expect(testObject.deleteCount, 1);

      // Trigger final delete
      SkiaObjects.postFrameCleanUp();
      expect(SkiaObjects.resurrectableObjects, isEmpty);
      expect(fakeRasterizer.addPostFrameCallbackCount, 1);
      expect(testObject.createDefaultCount, 1);
      expect(testObject.resurrectCount, 1);
      expect(testObject.deleteCount, 2);
    });

    test('is added to SkiaObjects cache if expensive', () {
      final TestSkiaObject object1 = TestSkiaObject(isExpensive: true);
      expect(SkiaObjects.expensiveCache.length, 1);
      expect(SkiaObjects.expensiveCache.debugContains(object1), isTrue);

      final TestSkiaObject object2 = TestSkiaObject(isExpensive: true);
      expect(SkiaObjects.expensiveCache.length, 2);
      expect(SkiaObjects.expensiveCache.debugContains(object2), isTrue);

      SkiaObjects.postFrameCleanUp();
      expect(SkiaObjects.expensiveCache.length, 2);
      expect(SkiaObjects.expensiveCache.debugContains(object1), isTrue);
      expect(SkiaObjects.expensiveCache.debugContains(object2), isTrue);

      /// Add 3 more objects to the cache to overflow it.
      TestSkiaObject(isExpensive: true);
      TestSkiaObject(isExpensive: true);
      TestSkiaObject(isExpensive: true);
      expect(SkiaObjects.expensiveCache.length, 5);
      expect(SkiaObjects.cachesToResize.length, 1);

      SkiaObjects.postFrameCleanUp();
      expect(object1.deleteCount, 1);
      expect(object2.deleteCount, 1);
      expect(SkiaObjects.expensiveCache.length, 3);
      expect(SkiaObjects.expensiveCache.debugContains(object1), isFalse);
      expect(SkiaObjects.expensiveCache.debugContains(object2), isFalse);
    });
  });

  group(SkiaObjectBox, () {
    test('Records stack traces and respects refcounts', () async {
      final ZoneSpy spy = ZoneSpy();
      spy.run(() {
        Instrumentation.enabled = true;
        TestSkDeletableMock.deleteCount = 0;
        TestBoxWrapper.resurrectCount = 0;
        final TestBoxWrapper original = TestBoxWrapper();

        expect(original.box.debugGetStackTraces().length, 1);
        expect(original.box.refCount, 1);
        expect(original.box.isDeletedPermanently, isFalse);

        final TestBoxWrapper clone = original.clone();
        expect(clone.box, same(original.box));
        expect(clone.box.debugGetStackTraces().length, 2);
        expect(clone.box.refCount, 2);
        expect(original.box.debugGetStackTraces().length, 2);
        expect(original.box.refCount, 2);
        expect(original.box.isDeletedPermanently, isFalse);

        original.dispose();

        testCollector.collectNow();
        expect(TestSkDeletableMock.deleteCount, 0);

        spy.fakeAsync.elapse(const Duration(seconds: 2));
        expect(
          spy.printLog,
          <String>[
            'Engine counters:\n  TestSkDeletable created: 1\n'
          ],
        );

        expect(clone.box.debugGetStackTraces().length, 1);
        expect(clone.box.refCount, 1);
        expect(original.box.debugGetStackTraces().length, 1);
        expect(original.box.refCount, 1);

        clone.dispose();
        expect(clone.box.debugGetStackTraces().length, 0);
        expect(clone.box.refCount, 0);
        expect(original.box.debugGetStackTraces().length, 0);
        expect(original.box.refCount, 0);
        expect(original.box.isDeletedPermanently, isTrue);

        testCollector.collectNow();
        expect(TestSkDeletableMock.deleteCount, 1);
        expect(TestBoxWrapper.resurrectCount, 0);

        expect(() => clone.box.unref(clone), throwsAssertionError);
        spy.printLog.clear();
        spy.fakeAsync.elapse(const Duration(seconds: 2));
        expect(
          spy.printLog,
          <String>[
            'Engine counters:\n  TestSkDeletable created: 1\n  TestSkDeletable deleted: 1\n'
          ],
        );
        Instrumentation.enabled = false;
      });
    });

    test('Can resurrect Skia objects', () async {
      TestSkDeletableMock.deleteCount = 0;
      TestBoxWrapper.resurrectCount = 0;
      final TestBoxWrapper object = TestBoxWrapper();
      expect(TestSkDeletableMock.deleteCount, 0);
      expect(TestBoxWrapper.resurrectCount, 0);

      // Test 3 cycles of delete/resurrect.
      for (int i = 0; i < 3; i++) {
        object.box.delete();
        object.box.didDelete();
        expect(TestSkDeletableMock.deleteCount, i + 1);
        expect(TestBoxWrapper.resurrectCount, i);
        expect(object.box.isDeletedTemporarily, isTrue);
        expect(object.box.isDeletedPermanently, isFalse);

        expect(object.box.skiaObject, isNotNull);
        expect(TestSkDeletableMock.deleteCount, i + 1);
        expect(TestBoxWrapper.resurrectCount, i + 1);
        expect(object.box.isDeletedTemporarily, isFalse);
        expect(object.box.isDeletedPermanently, isFalse);
      }

      object.dispose();
      expect(object.box.isDeletedPermanently, isTrue);
    });

    test('Can dispose temporarily deleted object', () async {
      TestSkDeletableMock.deleteCount = 0;
      TestBoxWrapper.resurrectCount = 0;
      final TestBoxWrapper object = TestBoxWrapper();
      expect(TestSkDeletableMock.deleteCount, 0);
      expect(TestBoxWrapper.resurrectCount, 0);

      object.box.delete();
      object.box.didDelete();
      expect(TestSkDeletableMock.deleteCount, 1);
      expect(TestBoxWrapper.resurrectCount, 0);
      expect(object.box.isDeletedTemporarily, isTrue);
      expect(object.box.isDeletedPermanently, isFalse);

      object.dispose();
      expect(object.box.isDeletedPermanently, isTrue);
    });
  });

  group('$SynchronousSkiaObjectCache', () {
    test('is initialized empty', () {
      expect(SynchronousSkiaObjectCache(10), hasLength(0));
    });

    test('adds objects', () {
      final SynchronousSkiaObjectCache cache = SynchronousSkiaObjectCache(2);
      cache.add(TestSelfManagedObject());
      expect(cache, hasLength(1));
      cache.add(TestSelfManagedObject());
      expect(cache, hasLength(2));
    });

    test('forbids adding the same object twice', () {
      final SynchronousSkiaObjectCache cache = SynchronousSkiaObjectCache(2);
      final TestSelfManagedObject object = TestSelfManagedObject();
      cache.add(object);
      expect(cache, hasLength(1));
      expect(() => cache.add(object), throwsAssertionError);
    });

    void expectObjectInCache(
      SynchronousSkiaObjectCache cache,
      TestSelfManagedObject object,
    ) {
      expect(cache.debugContains(object), isTrue);
      expect(object._skiaObject, isNotNull);
    }

    void expectObjectNotInCache(
      SynchronousSkiaObjectCache cache,
      TestSelfManagedObject object,
    ) {
      expect(cache.debugContains(object), isFalse);
      expect(object._skiaObject, isNull);
    }

    test('respects maximumSize', () {
      final SynchronousSkiaObjectCache cache = SynchronousSkiaObjectCache(2);
      final TestSelfManagedObject object1 = TestSelfManagedObject();
      final TestSelfManagedObject object2 = TestSelfManagedObject();
      final TestSelfManagedObject object3 = TestSelfManagedObject();
      final TestSelfManagedObject object4 = TestSelfManagedObject();

      cache.add(object1);
      expect(cache, hasLength(1));
      expectObjectInCache(cache, object1);

      cache.add(object2);
      expect(cache, hasLength(2));
      expectObjectInCache(cache, object1);
      expectObjectInCache(cache, object2);

      cache.add(object3);
      expect(cache, hasLength(2));
      expectObjectNotInCache(cache, object1);
      expectObjectInCache(cache, object2);
      expectObjectInCache(cache, object3);

      cache.add(object4);
      expect(cache, hasLength(2));
      expectObjectNotInCache(cache, object1);
      expectObjectNotInCache(cache, object2);
      expectObjectInCache(cache, object3);
      expectObjectInCache(cache, object4);
    });

    test('uses RLU strategy', () {
      final SynchronousSkiaObjectCache cache = SynchronousSkiaObjectCache(2);
      final TestSelfManagedObject object1 = TestSelfManagedObject();
      final TestSelfManagedObject object2 = TestSelfManagedObject();
      final TestSelfManagedObject object3 = TestSelfManagedObject();
      final TestSelfManagedObject object4 = TestSelfManagedObject();

      cache.add(object1);
      expectObjectInCache(cache, object1);
      cache.add(object2);
      expectObjectInCache(cache, object2);
      cache.add(object3);
      expectObjectInCache(cache, object3);
      expectObjectNotInCache(cache, object1);

      cache.markUsed(object2);
      cache.add(object4);
      expectObjectInCache(cache, object2);
      expectObjectNotInCache(cache, object3);
      expectObjectInCache(cache, object4);
    });
  });
}

/// A simple class that wraps a [SkiaObjectBox].
///
/// Can be [clone]d such that the clones share the same ref counted box.
class TestBoxWrapper implements StackTraceDebugger {
  TestBoxWrapper() {
    if (assertionsEnabled) {
      _debugStackTrace = StackTrace.current;
    }
    box = SkiaObjectBox<TestBoxWrapper, TestSkDeletable>.resurrectable(
        this, TestSkDeletable(), () {
      resurrectCount += 1;
      return TestSkDeletable();
    });
  }

  TestBoxWrapper.cloneOf(this.box) {
    if (assertionsEnabled) {
      _debugStackTrace = StackTrace.current;
    }
    box.ref(this);
  }

  static int resurrectCount = 0;

  @override
  StackTrace get debugStackTrace => _debugStackTrace;
  late StackTrace _debugStackTrace;

  late SkiaObjectBox<TestBoxWrapper, TestSkDeletable> box;

  void dispose() {
    box.unref(this);
  }

  TestBoxWrapper clone() => TestBoxWrapper.cloneOf(box);
}

class TestSkDeletableMock {
  static int deleteCount = 0;

  bool isDeleted() => _isDeleted;
  bool _isDeleted = false;

  void delete() {
    expect(_isDeleted, isFalse,
        reason:
            'CanvasKit does not allow deleting the same object more than once.');
    _isDeleted = true;
    deleteCount++;
  }

  JsConstructor get constructor => TestJsConstructor(name: 'TestSkDeletable');
}

@JS()
@anonymous
@staticInterop
class TestSkDeletable implements SkDeletable {
  factory TestSkDeletable() {
    final TestSkDeletableMock mock = TestSkDeletableMock();
    return TestSkDeletable._(
        isDeleted: allowInterop(() => mock.isDeleted()),
        delete: allowInterop(() => mock.delete()),
        constructor: mock.constructor);
  }

  external factory TestSkDeletable._({
    bool Function() isDeleted,
    void Function() delete,
    JsConstructor constructor});
}

@JS()
@anonymous
@staticInterop
class TestJsConstructor implements JsConstructor {
  external factory TestJsConstructor({String name});
}

class TestSkiaObject extends ManagedSkiaObject<SkPaint> {
  TestSkiaObject({this.isExpensive = false});

  int createDefaultCount = 0;
  int resurrectCount = 0;
  int deleteCount = 0;

  final bool isExpensive;

  @override
  SkPaint createDefault() {
    createDefaultCount++;
    return SkPaint();
  }

  @override
  SkPaint resurrect() {
    resurrectCount++;
    return SkPaint();
  }

  @override
  void delete() {
    rawSkiaObject?.delete();
    deleteCount++;
  }

  @override
  bool get isResurrectionExpensive => isExpensive;
}

class FakeRasterizer implements Rasterizer {
  int addPostFrameCallbackCount = 0;

  @override
  void addPostFrameCallback(VoidCallback callback) {
    addPostFrameCallbackCount++;
  }

  @override
  CompositorContext get context => throw UnimplementedError();

  @override
  void draw(LayerTree layerTree) {
    throw UnimplementedError();
  }

  @override
  void setSkiaResourceCacheMaxBytes(int bytes) {
    throw UnimplementedError();
  }

  @override
  void debugRunPostFrameCallbacks() {
    throw UnimplementedError();
  }
}

class TestSelfManagedObject extends SkiaObject<TestSkDeletable> {
  TestSkDeletable? _skiaObject = TestSkDeletable();

  @override
  void delete() {
    _skiaObject!.delete();
  }

  @override
  void didDelete() {
    _skiaObject = null;
  }

  @override
  TestSkDeletable get skiaObject => throw UnimplementedError();
}
