'use strict';

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

var fromString = require('uint8arrays/from-string');
var isIpfs = require('is-ipfs');
var nanoid = require('nanoid');
var base64 = require('multiformats/bases/base64');
var chai_js = require('aegir/utils/chai.js');
var mocha = require('../utils/mocha.js');
var all = require('it-all');
var env_js = require('ipfs-utils/src/env.js');
var ipfsOptionsWebsocketsFilterAll = require('../utils/ipfs-options-websockets-filter-all.js');
var merge = require('merge-options');

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

var isIpfs__default = /*#__PURE__*/_interopDefaultLegacy(isIpfs);
var all__default = /*#__PURE__*/_interopDefaultLegacy(all);
var merge__default = /*#__PURE__*/_interopDefaultLegacy(merge);

function testResolve(factory, options) {
  const ipfsOptions = ipfsOptionsWebsocketsFilterAll.ipfsOptionsWebsocketsFilterAll();
  const describe = mocha.getDescribe(options);
  const it = mocha.getIt(options);
  describe('.resolve', function () {
    this.timeout(60 * 1000);
    let ipfs;
    let ipfsId;
    before(async () => {
      ipfs = (await factory.spawn({
        type: 'proc',
        ipfsOptions: merge__default["default"](ipfsOptions, { config: { Routing: { Type: 'none' } } })
      })).api;
      ipfsId = await ipfs.id();
    });
    after(() => factory.clean());
    it('should resolve an IPFS hash', async () => {
      const content = fromString.fromString('Hello world');
      const {cid} = await ipfs.add(content);
      const path = await ipfs.resolve(`/ipfs/${ cid }`);
      chai_js.expect(path).to.equal(`/ipfs/${ cid }`);
    });
    it('should resolve an IPFS hash and return a base64url encoded CID in path', async () => {
      const {cid} = await ipfs.add(fromString.fromString('base64url encoded'), { cidVersion: 1 });
      const path = await ipfs.resolve(`/ipfs/${ cid }`, { cidBase: 'base64url' });
      const [, , cidStr] = path.split('/');
      chai_js.expect(cidStr).to.equal(cid.toString(base64.base64url));
    });
    it('should resolve an IPFS path link', async () => {
      const path = 'path/to/testfile.txt';
      const content = fromString.fromString('Hello world');
      const [{cid: fileCid}, , , {cid: rootCid}] = await all__default["default"](ipfs.addAll([{
          path,
          content
        }], { wrapWithDirectory: true }));
      const resolve = await ipfs.resolve(`/ipfs/${ rootCid }/${ path }`);
      chai_js.expect(resolve).to.equal(`/ipfs/${ fileCid }`);
    });
    it('should resolve up to the last node', async () => {
      const content = { path: { to: { file: nanoid.nanoid() } } };
      const options = {
        storeCodec: 'dag-cbor',
        hashAlg: 'sha2-256'
      };
      const cid = await ipfs.dag.put(content, options);
      const path = `/ipfs/${ cid }/path/to/file`;
      const resolved = await ipfs.resolve(path);
      chai_js.expect(resolved).to.equal(path);
    });
    it('should resolve up to the last node across multiple nodes', async () => {
      const options = {
        storeCodec: 'dag-cbor',
        hashAlg: 'sha2-256'
      };
      const childCid = await ipfs.dag.put({ node: { with: { file: nanoid.nanoid() } } }, options);
      const parentCid = await ipfs.dag.put({ path: { to: childCid } }, options);
      const resolved = await ipfs.resolve(`/ipfs/${ parentCid }/path/to/node/with/file`);
      chai_js.expect(resolved).to.equal(`/ipfs/${ childCid }/node/with/file`);
    });
    it('should resolve an IPNS DNS link', async function () {
      this.retries(3);
      const resolved = await ipfs.resolve('/ipns/ipfs.io');
      chai_js.expect(isIpfs__default["default"].ipfsPath(resolved)).to.be.true();
    });
    it('should resolve IPNS link recursively by default', async function () {
      this.timeout(20 * 1000);
      const node = (await factory.spawn({
        type: env_js.isWebWorker ? 'go' : undefined,
        ipfsOptions: { config: { Routing: { Type: 'none' } } }
      })).api;
      const nodeId = await node.id();
      await ipfs.swarm.connect(nodeId.addresses[0]);
      const {path} = await ipfs.add(fromString.fromString('should resolve a record recursive === true'));
      const {id: keyId} = await ipfs.key.gen('key-name', {
        type: 'rsa',
        size: 2048
      });
      await ipfs.name.publish(path, { allowOffline: true });
      await ipfs.name.publish(`/ipns/${ ipfsId.id }`, {
        allowOffline: true,
        key: 'key-name',
        resolve: false
      });
      return chai_js.expect(ipfs.resolve(`/ipns/${ keyId }`)).to.eventually.equal(`/ipfs/${ path }`);
    });
    it('should resolve IPNS link non-recursively if recursive==false', async function () {
      this.timeout(20 * 1000);
      const node = (await factory.spawn({
        type: env_js.isWebWorker ? 'go' : undefined,
        ipfsOptions: { config: { Routing: { Type: 'none' } } }
      })).api;
      const nodeId = await node.id();
      await ipfs.swarm.connect(nodeId.addresses[0]);
      const {path} = await ipfs.add(fromString.fromString('should resolve an IPNS key if recursive === false'));
      const {id: keyId} = await ipfs.key.gen('new-key-name', {
        type: 'rsa',
        size: 2048
      });
      await ipfs.name.publish(path, { allowOffline: true });
      await ipfs.name.publish(`/ipns/${ ipfsId.id }`, {
        allowOffline: true,
        key: 'new-key-name',
        resolve: false
      });
      return chai_js.expect(ipfs.resolve(`/ipns/${ keyId }`, { recursive: false })).to.eventually.equal(`/ipns/${ ipfsId.id }`);
    });
  });
}

exports.testResolve = testResolve;
