// https://github.com/ensdomains/ui/blob/master/src/utils/contents.js
import contentHash from '@ensdomains/content-hash';
import { isHexString } from '@ethersproject/bytes';
import bs58 from 'bs58';
const supportedCodecs = ['ipns-ns', 'ipfs-ns', 'swarm-ns', 'onion', 'onion3'];

export function decodeContenthash(encoded) {
  let decoded, protocolType, error;
  if (encoded.error) {
    return { protocolType: null, decoded: encoded.error };
  }
  if (encoded) {
    try {
      decoded = contentHash.decode(encoded);
      const codec = contentHash.getCodec(encoded);
      if (codec === 'ipfs-ns') {
        // convert the ipfs from base58 to base32 (url host compatible)
        // if needed the hash can now be resolved through a secured origin gateway (<hash>.gateway.com)
        decoded = contentHash.helpers.cidV0ToV1Base32(decoded);

        protocolType = 'ipfs';
      } else if (codec === 'ipns-ns') {
        decoded = bs58
          .decode(decoded)
          .slice(2)
          .toString();
        protocolType = 'ipns';
      } else if (codec === 'swarm-ns') {
        protocolType = 'bzz';
      } else if (codec === 'onion') {
        protocolType = 'onion';
      } else if (codec === 'onion3') {
        protocolType = 'onion3';
      } else {
        decoded = encoded;
      }
    } catch (e) {
      error = e.message;
    }
  }
  return { protocolType, decoded, error };
}

export function validateContent(encoded) {
  return (
    contentHash.isHashOfType(encoded, contentHash.Types.ipfs) ||
    contentHash.isHashOfType(encoded, contentHash.Types.swarm)
  );
}

export function isValidContenthash(encoded) {
  try {
    const codec = contentHash.getCodec(encoded);
    return isHexString(encoded) && supportedCodecs.includes(codec);
  } catch (e) {
    console.log(e);
  }
}

export function encodeContenthash(text) {
  let content, contentType;
  let encoded: any = false;
  if (text) {
    const matched =
      text.match(/^(ipfs|ipns|bzz|onion|onion3):\/\/(.*)/) ||
      text.match(/\/(ipfs)\/(.*)/) ||
      text.match(/\/(ipns)\/(.*)/);
    if (matched) {
      contentType = matched[1];
      content = matched[2];
    }
    try {
      if (contentType === 'ipfs') {
        if (content.length >= 4) {
          encoded = '0x' + contentHash.encode('ipfs-ns', content);
        }
      } else if (contentType === 'ipns') {
        const bs58content = bs58.encode(
          Buffer.concat([
            Buffer.from([0, content.length]),
            Buffer.from(content)
          ])
        );
        encoded = '0x' + contentHash.encode('ipns-ns', bs58content);
      } else if (contentType === 'bzz') {
        if (content.length >= 4) {
          encoded = '0x' + contentHash.fromSwarm(content);
        }
      } else if (contentType === 'onion') {
        if (content.length == 16) {
          encoded = '0x' + contentHash.encode('onion', content);
        }
      } else if (contentType === 'onion3') {
        if (content.length == 56) {
          encoded = '0x' + contentHash.encode('onion3', content);
        }
      } else {
        console.warn('Unsupported protocol or invalid value', {
          contentType,
          text
        });
      }
    } catch (err) {
      console.warn('Error encoding content hash', { text, encoded });
      //throw 'Error encoding content hash'
    }
  }
  return encoded;
}
