#!/usr/bin/env node

var fs = require('fs');
var concat = require('concat-stream');
var base64url = require('../');
var cli = require('meow')({
  pkg: '../package.json',
  help: [
    'Usage: base64url [-hvD] [-b num] [-i in_file] [-o out_file]',
    '  -h, --help     display this message',
    '  -v, --version  display version info',
    '  -D, --decode   decodes input',
    '  -b, --break    break encoded string into num character lines',
    '  -i, --input    input file (default: stdin)',
    '  -o, --output   output file (default: stdout)'
  ].join('\n')
}, {
    boolean: [
    'D', 'decode',
    'h', 'help',
    'v', 'version',
  ],
  string: [
    'i', 'input',
    'o', 'output',
    'b', 'break',
  ],
});

var decode = cli.flags.d || cli.flags.decode;
var fn = decode && base64url.decode || base64url.encode;

function processStream(outputStream, breakLength) {
  outputStream = outputStream || process.stdout;
  return concat(function (buf) {
    outputStream.write(format(fn(buf), breakLength));
    process.exit(0);
  });
}

function format(string, breakLength) {
  if (!breakLength)
    return string;
  var regex = new RegExp('(.{' + breakLength + '})', 'g');
  return string.replace(regex, '$1\n');
}

function main() {
  var help = cli.flags.h || cli.flags.help;
  var version = cli.flags.v || cli.flags.version;

  if (help) {
    return cli.showHelp();
  }

  if (version) {
    console.log(cli.pkg.version);
    process.exit(0);
  }

  var breakLines = parseInt(cli.flags.b || cli.flags.break, 10);
  var inputFile = cli.flags.i || cli.flags.input;
  var outputFile = cli.flags.o || cli.flags.output;
  var writeStream = process.stdout;

  if (Array.isArray(inputFile))
    inputFile = inputFile.pop();

  if (cli.input.length > 0)
    inputFile = cli.input.pop();

  if (outputFile) {
    writeStream = fs.createWriteStream(outputFile);
    writeStream.on('error', fileStreamErrHandler(outputFile));
  }

  var outStream = processStream(writeStream, breakLines);

  if (!inputFile) {
    return process.stdin.pipe(outStream);
  }

  var readStream = fs.createReadStream(inputFile);
  readStream.on('error', fileStreamErrHandler(inputFile));

  return readStream.pipe(outStream);
}

function fileStreamErrHandler(file) {
  return function (err) {
    switch (err.code) {
     case 'ENOENT':
      console.error('Unable to open \'%s\': No such file or directory', file);
      break;
     case 'EISDIR':
      console.error('Unable to process \'%s\': Cannot operate on directories', file);
      break;
    }

    process.exit(err.errno || 1);
    console.log(err);
  };
}

main();
