'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var all = require('it-all');
var drain = require('it-drain');
var cid = require('multiformats/cid');
var sha2 = require('multiformats/hashes/sha2');
var chai_js = require('aegir/utils/chai.js');
var mocha = require('../utils/mocha.js');
var car = require('@ipld/car');
var raw = require('multiformats/codecs/raw');
var fromString = require('uint8arrays/from-string');
var loadFixture = require('aegir/utils/fixtures.js');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

function _interopNamespace(e) {
  if (e && e.__esModule) return e;
  var n = Object.create(null);
  if (e) {
    Object.keys(e).forEach(function (k) {
      if (k !== 'default') {
        var d = Object.getOwnPropertyDescriptor(e, k);
        Object.defineProperty(n, k, d.get ? d : {
          enumerable: true,
          get: function () { return e[k]; }
        });
      }
    });
  }
  n["default"] = e;
  return Object.freeze(n);
}

var all__default = /*#__PURE__*/_interopDefaultLegacy(all);
var drain__default = /*#__PURE__*/_interopDefaultLegacy(drain);
var raw__namespace = /*#__PURE__*/_interopNamespace(raw);
var loadFixture__default = /*#__PURE__*/_interopDefaultLegacy(loadFixture);

async function createBlocks(num) {
  const blocks = [];
  for (let i = 0; i < num; i++) {
    const bytes = fromString.fromString('block-' + Math.random());
    const digest = await sha2.sha256.digest(raw__namespace.encode(bytes));
    const cid$1 = cid.CID.create(1, raw__namespace.code, digest);
    blocks.push({
      bytes,
      cid: cid$1
    });
  }
  return blocks;
}
async function createCar(blocks) {
  const rootBlock = blocks[0];
  const {writer, out} = await car.CarWriter.create([rootBlock.cid]);
  writer.put(rootBlock).then(async () => {
    for (const block of blocks.slice(1)) {
      writer.put(block);
    }
    await writer.close();
  });
  return out;
}
function testImport(factory, options) {
  const describe = mocha.getDescribe(options);
  const it = mocha.getIt(options);
  describe('.dag.import', () => {
    let ipfs;
    before(async () => {
      ipfs = (await factory.spawn()).api;
    });
    after(() => factory.clean());
    it('should import a car file', async () => {
      const blocks = await createBlocks(5);
      const car = await createCar(blocks);
      const result = await all__default["default"](ipfs.dag.import(car));
      chai_js.expect(result).to.have.lengthOf(1);
      chai_js.expect(result).to.have.nested.deep.property('[0].root.cid', blocks[0].cid);
      for (const {cid} of blocks) {
        await chai_js.expect(ipfs.block.get(cid)).to.eventually.be.ok();
      }
      await chai_js.expect(all__default["default"](ipfs.pin.ls({ paths: blocks[0].cid }))).to.eventually.have.lengthOf(1).and.have.nested.property('[0].type', 'recursive');
    });
    it('should import a car file without pinning the roots', async () => {
      const blocks = await createBlocks(5);
      const car = await createCar(blocks);
      await all__default["default"](ipfs.dag.import(car, { pinRoots: false }));
      await chai_js.expect(all__default["default"](ipfs.pin.ls({ paths: blocks[0].cid }))).to.eventually.be.rejectedWith(/is not pinned/);
    });
    it('should import multiple car files', async () => {
      const blocks1 = await createBlocks(5);
      const car1 = await createCar(blocks1);
      const blocks2 = await createBlocks(5);
      const car2 = await createCar(blocks2);
      const result = await all__default["default"](ipfs.dag.import([
        car1,
        car2
      ]));
      chai_js.expect(result).to.have.lengthOf(2);
      chai_js.expect(result).to.deep.include({
        root: {
          cid: blocks1[0].cid,
          pinErrorMsg: ''
        }
      });
      chai_js.expect(result).to.deep.include({
        root: {
          cid: blocks2[0].cid,
          pinErrorMsg: ''
        }
      });
      for (const {cid} of blocks1) {
        await chai_js.expect(ipfs.block.get(cid)).to.eventually.be.ok();
      }
      for (const {cid} of blocks2) {
        await chai_js.expect(ipfs.block.get(cid)).to.eventually.be.ok();
      }
    });
    it('should import car with roots but no blocks', async () => {
      const input = loadFixture__default["default"]('test/fixtures/car/combined_naked_roots_genesis_and_128.car', 'interface-ipfs-core');
      const reader = await car.CarReader.fromBytes(input);
      const cids = await reader.getRoots();
      chai_js.expect(cids).to.have.lengthOf(2);
      const result1 = await all__default["default"](ipfs.dag.import(async function* () {
        yield input;
      }()));
      chai_js.expect(result1).to.deep.include({
        root: {
          cid: cids[0],
          pinErrorMsg: 'blockstore: block not found'
        }
      });
      chai_js.expect(result1).to.deep.include({
        root: {
          cid: cids[1],
          pinErrorMsg: 'blockstore: block not found'
        }
      });
      await drain__default["default"](ipfs.dag.import(async function* () {
        yield loadFixture__default["default"]('test/fixtures/car/lotus_devnet_genesis_shuffled_nulroot.car', 'interface-ipfs-core');
      }()));
      const result2 = await all__default["default"](ipfs.dag.import(async function* () {
        yield input;
      }()));
      chai_js.expect(result2).to.deep.include({
        root: {
          cid: cids[0],
          pinErrorMsg: ''
        }
      });
      chai_js.expect(result2).to.deep.include({
        root: {
          cid: cids[1],
          pinErrorMsg: 'blockstore: block not found'
        }
      });
      await drain__default["default"](ipfs.dag.import(async function* () {
        yield loadFixture__default["default"]('test/fixtures/car/lotus_testnet_export_128.car', 'interface-ipfs-core');
      }()));
      const result3 = await all__default["default"](ipfs.dag.import(async function* () {
        yield input;
      }()));
      chai_js.expect(result3).to.deep.include({
        root: {
          cid: cids[0],
          pinErrorMsg: ''
        }
      });
      chai_js.expect(result3).to.deep.include({
        root: {
          cid: cids[1],
          pinErrorMsg: ''
        }
      });
    });
    it('should import lotus devnet genesis shuffled nulroot', async () => {
      const input = loadFixture__default["default"]('test/fixtures/car/lotus_devnet_genesis_shuffled_nulroot.car', 'interface-ipfs-core');
      const reader = await car.CarReader.fromBytes(input);
      const cids = await reader.getRoots();
      chai_js.expect(cids).to.have.lengthOf(1);
      chai_js.expect(cids[0].toString()).to.equal('bafkqaaa');
      const result = await all__default["default"](ipfs.dag.import(async function* () {
        yield input;
      }()));
      chai_js.expect(result).to.have.nested.deep.property('[0].root.cid', cids[0]);
    });
  });
}

exports.testImport = testImport;
