var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import chaiAsPromised from 'chai-as-promised';
import chai, { expect } from 'chai';
import { ArrayUtility } from '../../src/utils/array.js';
import { Cid } from '../../src/utils/cid.js';
import { DataStoreLevel } from '../../src/store/data-store-level.js';
import { DataStream } from '../../src/index.js';
import { TestDataGenerator } from '../utils/test-data-generator.js';
chai.use(chaiAsPromised);
let store;
describe('DataStore Test Suite', () => {
    if (process.env.TESTSOFF === 'true') {
        return;
    }
    before(() => __awaiter(void 0, void 0, void 0, function* () {
        store = new DataStoreLevel({ blockstoreLocation: 'tests/data/TEST-DATASTORE' });
        yield store.open();
    }));
    beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
        yield store.clear(); // clean up before each test rather than after so that a test does not depend on other tests to do the clean up
    }));
    after(() => __awaiter(void 0, void 0, void 0, function* () {
        yield store.close();
    }));
    describe('put', function () {
        it('should return the correct size of the data stored', () => __awaiter(this, void 0, void 0, function* () {
            const tenant = yield TestDataGenerator.randomCborSha256Cid();
            const messageCid = yield TestDataGenerator.randomCborSha256Cid();
            let dataSizeInBytes = 10;
            // iterate through order of magnitude in size until hitting 10MB
            while (dataSizeInBytes <= 10000000) {
                const dataBytes = TestDataGenerator.randomBytes(dataSizeInBytes);
                const dataStream = DataStream.fromBytes(dataBytes);
                const dataCid = yield Cid.computeDagPbCidFromBytes(dataBytes);
                const { dataSize } = yield store.put(tenant, messageCid, dataCid, dataStream);
                expect(dataSize).to.equal(dataSizeInBytes);
                const result = (yield store.get(tenant, messageCid, dataCid));
                const storedDataBytes = yield DataStream.toBytes(result.dataStream);
                expect(storedDataBytes).to.eql(dataBytes);
                dataSizeInBytes *= 10;
            }
        }));
    });
    describe('get', function () {
        it('should return `undefined if unable to find the data specified`', () => __awaiter(this, void 0, void 0, function* () {
            const tenant = yield TestDataGenerator.randomCborSha256Cid();
            const messageCid = yield TestDataGenerator.randomCborSha256Cid();
            const randomCid = yield TestDataGenerator.randomCborSha256Cid();
            const result = yield store.get(tenant, messageCid, randomCid);
            expect(result).to.be.undefined;
        }));
        it('should return `undefined if the dataCid is different than the dataStream`', () => __awaiter(this, void 0, void 0, function* () {
            const tenant = yield TestDataGenerator.randomCborSha256Cid();
            const messageCid = yield TestDataGenerator.randomCborSha256Cid();
            const randomCid = yield TestDataGenerator.randomCborSha256Cid();
            const dataBytes = TestDataGenerator.randomBytes(10000000);
            const dataStream = DataStream.fromBytes(dataBytes);
            const { dataCid } = yield store.put(tenant, messageCid, randomCid, dataStream);
            expect(dataCid).to.not.equal(randomCid);
            const result = yield store.get(tenant, messageCid, randomCid);
            expect(result).to.be.undefined;
        }));
    });
    describe('associate', function () {
        it('should return `false` if tenant missing', () => __awaiter(this, void 0, void 0, function* () {
            const tenant = yield TestDataGenerator.randomCborSha256Cid();
            const messageCid = yield TestDataGenerator.randomCborSha256Cid();
            const randomCid = yield TestDataGenerator.randomCborSha256Cid();
            const keysBeforeAssociate = yield ArrayUtility.fromAsyncGenerator(store.blockstore.db.keys());
            expect(keysBeforeAssociate.length).to.equal(0);
            const result = yield store.associate(tenant, messageCid, randomCid);
            expect(result).to.be.undefined;
            const keysAfterAssociate = yield ArrayUtility.fromAsyncGenerator(store.blockstore.db.keys());
            expect(keysAfterAssociate.length).to.equal(0);
        }));
        it('should return `false` if data missing', () => __awaiter(this, void 0, void 0, function* () {
            const tenant = yield TestDataGenerator.randomCborSha256Cid();
            const messageCid = yield TestDataGenerator.randomCborSha256Cid();
            const randomCid = yield TestDataGenerator.randomCborSha256Cid();
            const dataBytes = TestDataGenerator.randomBytes(10);
            const dataStream = DataStream.fromBytes(dataBytes);
            const { dataCid } = yield store.put(tenant, messageCid, randomCid, dataStream);
            expect(dataCid).to.not.equal(randomCid);
            const keysBeforeAssociate = yield ArrayUtility.fromAsyncGenerator(store.blockstore.db.keys());
            expect(keysBeforeAssociate.length).to.equal(2);
            const result = yield store.associate(tenant, messageCid, randomCid);
            expect(result).to.be.undefined;
            const keysAfterAssociate = yield ArrayUtility.fromAsyncGenerator(store.blockstore.db.keys());
            expect(keysAfterAssociate.length).to.equal(2);
        }));
        it('should return the root CID', () => __awaiter(this, void 0, void 0, function* () {
            const tenant = yield TestDataGenerator.randomCborSha256Cid();
            const messageCid = yield TestDataGenerator.randomCborSha256Cid();
            const dataBytes = TestDataGenerator.randomBytes(10000000);
            const dataStream = DataStream.fromBytes(dataBytes);
            const dataCid = yield Cid.computeDagPbCidFromBytes(dataBytes);
            yield store.put(tenant, messageCid, dataCid, dataStream);
            const keysBeforeDelete = yield ArrayUtility.fromAsyncGenerator(store.blockstore.db.keys());
            expect(keysBeforeDelete.length).to.equal(41);
            const result = (yield store.associate(tenant, messageCid, dataCid));
            expect(result.dataCid).to.equal(dataCid);
            expect(result.dataSize).to.equal(10000000);
            const keysAfterDelete = yield ArrayUtility.fromAsyncGenerator(store.blockstore.db.keys());
            expect(keysAfterDelete.length).to.equal(41);
        }));
    });
    describe('delete', function () {
        it('should not leave anything behind when deleting a the root CID', () => __awaiter(this, void 0, void 0, function* () {
            const tenant = yield TestDataGenerator.randomCborSha256Cid();
            const messageCid = yield TestDataGenerator.randomCborSha256Cid();
            const dataBytes = TestDataGenerator.randomBytes(10000000);
            const dataStream = DataStream.fromBytes(dataBytes);
            const dataCid = yield Cid.computeDagPbCidFromBytes(dataBytes);
            yield store.put(tenant, messageCid, dataCid, dataStream);
            const keysBeforeDelete = yield ArrayUtility.fromAsyncGenerator(store.blockstore.db.keys());
            expect(keysBeforeDelete.length).to.equal(41);
            yield store.delete(tenant, messageCid, dataCid);
            const keysAfterDelete = yield ArrayUtility.fromAsyncGenerator(store.blockstore.db.keys());
            expect(keysAfterDelete.length).to.equal(0);
        }));
    });
});
//# sourceMappingURL=data-store.spec.js.map