// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library IndexedDB4Test;

import 'package:async_helper/async_minitest.dart';
import 'dart:async';
import 'dart:html' as html;
import 'dart:indexed_db';

// Test for KeyRange and Cursor.

const String DB_NAME = 'Test4';
const String STORE_NAME = 'TEST';
const int VERSION = 1;

Future<Database> createAndOpenDb() {
  return html.window.indexedDB!.deleteDatabase(DB_NAME).then((_) {
    return html.window.indexedDB!.open(DB_NAME, version: VERSION,
        onUpgradeNeeded: (e) {
      var db = e.target.result;
      db.createObjectStore(STORE_NAME);
    });
  });
}

Future<Database> writeItems(Database db) {
  Future<Object?> write(index) {
    var transaction = db.transaction(STORE_NAME, 'readwrite');
    return transaction
        .objectStore(STORE_NAME)
        .put({'content': 'Item $index'}, index) as Future<Object?>;
  }

  var future = write(0);
  for (var i = 1; i < 100; ++i) {
    future = future.then((_) => write(i));
  }

  // Chain on the DB so we return it at the end.
  return future.then((_) => db);
}

Future<Database> setupDb() {
  return createAndOpenDb().then(writeItems);
}

testRange(db, range, expectedFirst, expectedLast) {
  Transaction txn = db.transaction(STORE_NAME, 'readonly');
  ObjectStore objectStore = txn.objectStore(STORE_NAME);
  var cursors = objectStore
      .openCursor(range: range, autoAdvance: true)
      .asBroadcastStream();

  int lastKey = 0;
  cursors.listen((cursor) {
    lastKey = cursor.key as int;
    var value = cursor.value;
    expect(value['content'], 'Item ${cursor.key}');
  });

  if (expectedFirst != null) {
    cursors.first.then((cursor) {
      expect(cursor.key, expectedFirst);
    });
  }
  if (expectedLast != null) {
    cursors.last.then((cursor) {
      expect(lastKey, expectedLast);
    });
  }

  return cursors.length.then((length) {
    if (expectedFirst == null) {
      expect(length, 0);
    } else {
      expect(length, expectedLast - expectedFirst + 1);
    }
  });
}

main() async {
  // Don't bother with these tests if it's unsupported.
  // Support is tested in indexeddb_1_test
  if (IdbFactory.supported) {
    var db = await setupDb();
    test('only1', () => testRange(db, new KeyRange.only(55), 55, 55));
    test('only2', () => testRange(db, new KeyRange.only(100), null, null));
    test('only3', () => testRange(db, new KeyRange.only(-1), null, null));

    test('lower1', () => testRange(db, new KeyRange.lowerBound(40), 40, 99));
    // OPTIONALS lower2() => testRange(db, new KeyRange.lowerBound(40, open: true), 41, 99);
    test('lower2',
        () => testRange(db, new KeyRange.lowerBound(40, true), 41, 99));
    // OPTIONALS lower3() => testRange(db, new KeyRange.lowerBound(40, open: false), 40, 99);
    test('lower3',
        () => testRange(db, new KeyRange.lowerBound(40, false), 40, 99));

    test('upper1', () => testRange(db, new KeyRange.upperBound(40), 0, 40));
    // OPTIONALS upper2() => testRange(db, new KeyRange.upperBound(40, open: true), 0, 39);
    test('upper2',
        () => testRange(db, new KeyRange.upperBound(40, true), 0, 39));
    // upper3() => testRange(db, new KeyRange.upperBound(40, open: false), 0, 40);
    test('upper3',
        () => testRange(db, new KeyRange.upperBound(40, false), 0, 40));

    test('bound1', () => testRange(db, new KeyRange.bound(20, 30), 20, 30));

    test('bound2', () => testRange(db, new KeyRange.bound(-100, 200), 0, 99));

    bound3() =>
        // OPTIONALS testRange(db, new KeyRange.bound(20, 30, upperOpen: true),
        testRange(db, new KeyRange.bound(20, 30, false, true), 20, 29);

    bound4() =>
        // OPTIONALS testRange(db, new KeyRange.bound(20, 30, lowerOpen: true),
        testRange(db, new KeyRange.bound(20, 30, true), 21, 30);

    bound5() =>
        // OPTIONALS testRange(db, new KeyRange.bound(20, 30, lowerOpen: true, upperOpen: true),
        testRange(db, new KeyRange.bound(20, 30, true, true), 21, 29);
  }
}
