'use strict';

var Command = require('ronin').Command;
var utils = require('../../utils');
var bs58 = require('bs58');
var bl = require('bl');
var fs = require('fs');
var mDAG = require('ipfs-merkle-dag');
var DAGNode = mDAG.DAGNode;
var debug = require('debug');
var log = debug('cli:object');
log.error = debug('cli:object:error');

function parseJSONBuffer(buf) {
  try {
    var parsed = JSON.parse(buf.toString());
    return {
      data: new Buffer(parsed.Data),
      links: parsed.Links ? parsed.Links.map(function (link) {
        return {
          name: link.Name,
          hash: new Buffer(bs58.decode(link.Hash)),
          size: link.Size
        };
      }) : []
    };
  } catch (err) {
    log.error(err);
    throw new Error('failed to parse JSON: ' + err);
  }
}

function parseAndAddNode(buf) {
  utils.getIPFS(function (err, ipfs) {
    if (err) {
      throw err;
    }
    if (utils.isDaemonOn()) {
      return ipfs.object.put(buf, 'json', function (err, obj) {
        if (err) {
          log.error(err);
          throw err;
        }

        console.log('added', obj.Hash);
      });
    }

    var parsed = parseJSONBuffer(buf);
    var dagNode = new DAGNode(parsed.data, parsed.links);
    ipfs.object.put(dagNode, function (err, obj) {
      if (err) {
        log.error(err);
        throw err;
      }

      console.log('added', bs58.encode(dagNode.multihash()).toString());
    });
  });
}

module.exports = Command.extend({
  desc: 'Stores input as a DAG object, outputs its key',

  options: {},

  run: function run(filePath) {
    if (filePath) {
      return parseAndAddNode(fs.readFileSync(filePath));
    }

    process.stdin.pipe(bl(function (err, input) {
      if (err) {
        log.error(err);
        throw err;
      }

      parseAndAddNode(input);
    }));
  }
});