#!/usr/bin/env node
// vim: set filetype=javascript:
'use strict';

var glob = require('glob');
var fs = require('fs');

/**
 *
 *  dotob <pattern> -f require -t dependencies.npm
 *
 */
var dotob = require('../index.js');
var program = require('commander');
var pkg = require('../package.json');

program
  .version(pkg.version)
  .usage('[options]')
  .option('-p, --pattern [pattern]', 'Files pattern to match or just the file')
  .option('-f, --from [path,..]', 'From path')
  .option('-t, --to [path,..]', 'To path (number of replacements must match --to values)')
  .option('-m, --merge', 'Merge into target')
  .option('-r, --remove [path,..]', 'Remove property')
  .option('-c, --dot', 'Convert object to dotted-key/value pair')
  .option('-s, --show', 'show all dotted paths')
  .option('-v, --verbose', 'Be verbose')
  .option('-d, --dry', 'Dry run do not modify files')
  .parse(process.argv);

function must(program, option) {
  if(!program.hasOwnProperty(option)) {
    console.log([
      'The', option, 'is required'
    ].join(' '));
    process.exit(1);
  }
}

must(program, 'pattern');

if (!program.remove && !program.dot && !program.show) {
  must(program, 'from');
  must(program, 'to');
}

var g = glob(program.pattern);

function finish(program, file, orig, json) {

  return function(err) {
    if (err) {
      throw err;
    } else {
      if (program.verbose) {
        if (orig !== JSON.stringify(json)) {
          console.log(file + ': updated.');
        } else {
          console.log(file + ': no matches.');
        }
      }
    }
  };
}

function splim(path) {
  return path.split(',')
    .map(function(val) { return val.trim();  });
}

function processFile(file) {

  fs.readFile(file, 'utf8', function(err, contents) {
    var json;

    if (err) {
      console.log(err);
      return;
    }

    try {
      json = JSON.parse(contents);

      if(program.show) {
        json = console.log(Object.keys(dotob.dot(json)).join('\n'));
        process.exit()
      } else if(program.dot) {
        console.log(dotob.dot(json));
        process.exit()
      }
      
      json = Array.isArray(json) ? json : [json];
      
      if(program.remove) {
        // support comma seperate list of removals
        splim(program.remove)
          .forEach(function(path) {
            for (var j = 0; j < json.length; j++) {
              dotob.remove(path, json[j]);
            }
          });
      } else {
        var from = splim(program.from);
        var to = splim(program.to);
        if (from.length === to.length) {
          for (var i = 0; i < from.length; i++) {
            for (var j = 0; j < json.length; j++) {
              dotob.move(
                from[i], to[i], json[j], program.merge
              );
            }
          }
        } else {
          console.error('--from and --to parameters are not of equal length');
        }
      }

      if(program.dry) {
        console.log(json);
        finish(program, file, contents, json)();
      } else {
        fs.writeFile(file, JSON.stringify(json, null, 2), finish(
          program, file, contents, json
        ));
      }
    } catch (e) {
      console.log(file + ': ');
      throw(e);
    }
  });
}

g.on('match', processFile);
