'use strict';

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

var fromString = require('uint8arrays/from-string');
var toString = require('uint8arrays/to-string');
var concat = require('uint8arrays/concat');
var index = require('./utils/index.js');
var cid = require('multiformats/cid');
var all = require('it-all');
var drain = require('it-drain');
var chai_js = require('aegir/utils/chai.js');
var mocha = require('./utils/mocha.js');
var testTimeout = require('./utils/test-timeout.js');
var ipfsUnixfsImporter = require('ipfs-unixfs-importer');
var blockstoreAdapter = require('./utils/blockstore-adapter.js');

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 testCat(factory, options) {
  const describe = mocha.getDescribe(options);
  const it = mocha.getIt(options);
  describe('.cat', function () {
    this.timeout(120 * 1000);
    let ipfs;
    before(async () => {
      ipfs = (await factory.spawn()).api;
    });
    after(() => factory.clean());
    before(() => Promise.all([
      all__default["default"](ipfsUnixfsImporter.importer({ content: index.fixtures.smallFile.data }, blockstoreAdapter(ipfs))),
      all__default["default"](ipfsUnixfsImporter.importer({ content: index.fixtures.bigFile.data }, blockstoreAdapter(ipfs)))
    ]));
    it('should respect timeout option when catting files', () => {
      return testTimeout(() => drain__default["default"](ipfs.cat(cid.CID.parse('QmPDqvcuA4AkhBLBuh2y49yhUB98rCnxPxa3eVNC1kAbS1'), { timeout: 1 })));
    });
    it('should cat with a base58 string encoded multihash', async () => {
      const data = concat.concat(await all__default["default"](ipfs.cat(index.fixtures.smallFile.cid)));
      chai_js.expect(toString.toString(data)).to.contain('Plz add me!');
    });
    it('should cat with a Uint8Array multihash', async () => {
      const cid = index.fixtures.smallFile.cid;
      const data = concat.concat(await all__default["default"](ipfs.cat(cid)));
      chai_js.expect(toString.toString(data)).to.contain('Plz add me!');
    });
    it('should cat with a CID object', async () => {
      const cid = index.fixtures.smallFile.cid;
      const data = concat.concat(await all__default["default"](ipfs.cat(cid)));
      chai_js.expect(toString.toString(data)).to.contain('Plz add me!');
    });
    it('should cat a file added as CIDv0 with a CIDv1', async () => {
      const input = fromString.fromString(`TEST${ Math.random() }`);
      const res = await all__default["default"](ipfsUnixfsImporter.importer([{
          content: async function* () {
            yield input;
          }()
        }], blockstoreAdapter(ipfs)));
      chai_js.expect(res).to.have.nested.property('[0].cid.version', 0);
      const cidv1 = res[0].cid.toV1();
      const output = concat.concat(await all__default["default"](ipfs.cat(cidv1)));
      chai_js.expect(output).to.eql(input);
    });
    it('should cat a file added as CIDv1 with a CIDv0', async () => {
      const input = fromString.fromString(`TEST${ Math.random() }`);
      const res = await all__default["default"](ipfsUnixfsImporter.importer([{
          content: async function* () {
            yield input;
          }()
        }], blockstoreAdapter(ipfs), {
        cidVersion: 1,
        rawLeaves: false
      }));
      chai_js.expect(res).to.have.nested.property('[0].cid.version', 1);
      const cidv0 = res[0].cid.toV0();
      const output = concat.concat(await all__default["default"](ipfs.cat(cidv0)));
      chai_js.expect(output.slice()).to.eql(input);
    });
    it('should cat a BIG file', async () => {
      const data = concat.concat(await all__default["default"](ipfs.cat(index.fixtures.bigFile.cid)));
      chai_js.expect(data.length).to.equal(index.fixtures.bigFile.data.length);
      chai_js.expect(data.slice()).to.eql(index.fixtures.bigFile.data);
    });
    it('should cat with IPFS path', async () => {
      const ipfsPath = '/ipfs/' + index.fixtures.smallFile.cid;
      const data = concat.concat(await all__default["default"](ipfs.cat(ipfsPath)));
      chai_js.expect(toString.toString(data)).to.contain('Plz add me!');
    });
    it('should cat with IPFS path, nested value', async () => {
      const fileToAdd = {
        path: 'a/testfile.txt',
        content: index.fixtures.smallFile.data
      };
      const filesAdded = await all__default["default"](ipfsUnixfsImporter.importer(fileToAdd, blockstoreAdapter(ipfs)));
      const file = await filesAdded.find(f => f.path === 'a');
      chai_js.expect(file).to.exist();
      if (!file) {
        throw new Error('No file added');
      }
      const data = concat.concat(await all__default["default"](ipfs.cat(`/ipfs/${ file.cid }/testfile.txt`)));
      chai_js.expect(toString.toString(data)).to.contain('Plz add me!');
    });
    it('should cat with IPFS path, deeply nested value', async () => {
      const fileToAdd = {
        path: 'a/b/testfile.txt',
        content: index.fixtures.smallFile.data
      };
      const filesAdded = await all__default["default"](ipfsUnixfsImporter.importer([fileToAdd], blockstoreAdapter(ipfs)));
      const file = filesAdded.find(f => f.path === 'a');
      chai_js.expect(file).to.exist();
      if (!file) {
        throw new Error('No file added');
      }
      const data = concat.concat(await all__default["default"](ipfs.cat(`/ipfs/${ file.cid }/b/testfile.txt`)));
      chai_js.expect(toString.toString(data)).to.contain('Plz add me!');
    });
    it('should error on invalid key', () => {
      const invalidCid = 'somethingNotMultihash';
      return chai_js.expect(drain__default["default"](ipfs.cat(invalidCid))).to.eventually.be.rejected();
    });
    it('should error on unknown path', () => {
      return chai_js.expect(drain__default["default"](ipfs.cat(index.fixtures.smallFile.cid + '/does-not-exist'))).to.eventually.be.rejected().and.be.an.instanceOf(Error).and.to.have.property('message').to.be.oneOf([
        'file does not exist',
        'no link named "does-not-exist" under Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP'
      ]);
    });
    it('should error on dir path', async () => {
      const file = {
        path: 'dir/testfile.txt',
        content: index.fixtures.smallFile.data
      };
      const filesAdded = await all__default["default"](ipfsUnixfsImporter.importer([file], blockstoreAdapter(ipfs)));
      chai_js.expect(filesAdded.length).to.equal(2);
      const files = filesAdded.filter(file => file.path === 'dir');
      chai_js.expect(files.length).to.equal(1);
      const dir = files[0];
      const err = await chai_js.expect(drain__default["default"](ipfs.cat(dir.cid))).to.eventually.be.rejected();
      chai_js.expect(err.message).to.contain('this dag node is a directory');
    });
    it('should export a chunk of a file', async () => {
      const offset = 1;
      const length = 3;
      const data = concat.concat(await all__default["default"](ipfs.cat(index.fixtures.smallFile.cid, {
        offset,
        length
      })));
      chai_js.expect(toString.toString(data)).to.equal('lz ');
    });
  });
}

exports.testCat = testCat;
