'use strict';

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

var fromString = require('uint8arrays/from-string');
var utils = require('./utils.js');
var chai_js = require('aegir/utils/chai.js');
var mocha = require('../utils/mocha.js');
var all = require('it-all');
var drain = require('it-drain');

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

var all__default = /*#__PURE__*/_interopDefaultLegacy(all);
var drain__default = /*#__PURE__*/_interopDefaultLegacy(drain);

function testAdd(factory, options) {
  const describe = mocha.getDescribe(options);
  const it = mocha.getIt(options);
  describe('.pin.add', function () {
    this.timeout(50 * 1000);
    let ipfs;
    before(async () => {
      ipfs = (await factory.spawn()).api;
      await drain__default["default"](ipfs.addAll(utils.fixtures.files.map(file => ({ content: file.data })), { pin: false }));
      await drain__default["default"](ipfs.addAll(utils.fixtures.directory.files.map(file => ({
        path: file.path,
        content: file.data
      })), { pin: false }));
    });
    after(() => factory.clean());
    beforeEach(() => {
      return utils.clearPins(ipfs);
    });
    it('should add a CID and return the added CID', async () => {
      const cid = await ipfs.pin.add(utils.fixtures.files[0].cid);
      chai_js.expect(cid).to.deep.equal(utils.fixtures.files[0].cid);
    });
    it('should add a pin with options and return the added CID', async () => {
      const cid = await ipfs.pin.add(utils.fixtures.files[0].cid, { recursive: false });
      chai_js.expect(cid).to.deep.equal(utils.fixtures.files[0].cid);
    });
    it('should add recursively', async () => {
      await ipfs.pin.add(utils.fixtures.directory.cid);
      await utils.expectPinned(ipfs, utils.fixtures.directory.cid, utils.pinTypes.recursive);
      const pinChecks = Object.values(utils.fixtures.directory.files).map(file => utils.expectPinned(ipfs, file.cid));
      return Promise.all(pinChecks);
    });
    it('should add directly', async () => {
      await ipfs.pin.add(utils.fixtures.directory.cid, { recursive: false });
      await utils.expectPinned(ipfs, utils.fixtures.directory.cid, utils.pinTypes.direct);
      await utils.expectNotPinned(ipfs, utils.fixtures.directory.files[0].cid);
    });
    it('should recursively pin parent of direct pin', async () => {
      await ipfs.pin.add(utils.fixtures.directory.files[0].cid, { recursive: false });
      await ipfs.pin.add(utils.fixtures.directory.cid);
      await utils.expectPinned(ipfs, utils.fixtures.directory.files[0].cid, utils.pinTypes.direct);
      await utils.expectPinned(ipfs, utils.fixtures.directory.files[0].cid, utils.pinTypes.indirect);
    });
    it('should fail to directly pin a recursive pin', async () => {
      await ipfs.pin.add(utils.fixtures.directory.cid);
      return chai_js.expect(ipfs.pin.add(utils.fixtures.directory.cid, { recursive: false })).to.eventually.be.rejectedWith(/already pinned recursively/);
    });
    it('should fail to pin a hash not in datastore', async function () {
      this.slow(3 * 1000);
      this.timeout(5 * 1000);
      const falseHash = `${ `${ utils.fixtures.directory.cid }`.slice(0, -2) }ss`;
      await chai_js.expect(ipfs.pin.add(falseHash, { timeout: '2s' })).to.eventually.be.rejected().with.property('name', 'TimeoutError');
    });
    it('needs all children in datastore to pin recursively', async function () {
      this.slow(3 * 1000);
      this.timeout(5 * 1000);
      await all__default["default"](ipfs.block.rm(utils.fixtures.directory.files[0].cid));
      await chai_js.expect(ipfs.pin.add(utils.fixtures.directory.cid, { timeout: '2s' })).to.eventually.be.rejected().with.property('name', 'TimeoutError');
    });
    it('should pin dag-cbor', async () => {
      const cid = await ipfs.dag.put({}, {
        storeCodec: 'dag-cbor',
        hashAlg: 'sha2-256'
      });
      await ipfs.pin.add(cid);
      const pins = await all__default["default"](ipfs.pin.ls());
      chai_js.expect(pins).to.deep.include({
        type: 'recursive',
        cid
      });
    });
    it('should pin raw', async () => {
      const cid = await ipfs.dag.put(new Uint8Array(0), {
        storeCodec: 'raw',
        hashAlg: 'sha2-256'
      });
      await ipfs.pin.add(cid);
      const pins = await all__default["default"](ipfs.pin.ls());
      chai_js.expect(pins).to.deep.include({
        type: 'recursive',
        cid
      });
    });
    it('should pin dag-cbor with dag-pb child', async () => {
      const child = await ipfs.dag.put({
        Data: fromString.fromString(`${ Math.random() }`),
        Links: []
      }, {
        storeCodec: 'dag-pb',
        hashAlg: 'sha2-256'
      });
      const parent = await ipfs.dag.put({ child }, {
        storeCodec: 'dag-cbor',
        hashAlg: 'sha2-256'
      });
      await ipfs.pin.add(parent, { recursive: true });
      const pins = await all__default["default"](ipfs.pin.ls());
      chai_js.expect(pins).to.deep.include({
        cid: parent,
        type: 'recursive'
      });
      chai_js.expect(pins).to.deep.include({
        cid: child,
        type: 'indirect'
      });
    });
  });
}

exports.testAdd = testAdd;
