// NPM Modules
import meow     from 'meow';
import stdin    from 'get-stdin';
import textr    from 'textr';

// Native Modules
import path     from 'path';
import fs       from 'fs';

/**
 * CLI app instance of Meow
 * More: https://www.npmjs.com/package/meow
 * @param  {Object|Array|String} Text that will be write on --help or -h
 * @param  {Object}              Minimist options (github.com/substack/minimist)
 * @return {Object}              A Meow CLI helper object
 */
const cli = meow(`
  Usage
    $ textr

  Options
    -t, --transforms    Array of transformers
    -o, --out-file      Write output to file
    -l, --locale        ISO 639 locale codes (en-us as default)
    -h, --help          Show this message

  Examples
    $ textr foo.md -t typographic-quotes -t typographic-quotes
    $ textr foo.md -t typographic-single-spaces,typographic-quotes
    $ cat foo.md | textr -l ru --transforms=typographic-single-spaces
    $ cat foo.md | textr -o bar.md
`,
  {
    default: {
      transforms: [],
    },
    alias: {
      t: 'transforms',
      o: 'out-file',
      l: 'locale',
      h: 'help'
    }
  }
);

/**
 * Resolve file name with current dir
 * @param  {String} file Any relative filename
 * @return {String}      Resolved path to file
 */
const cwd = file =>
  path.resolve(process.cwd(), file);

/**
 * Render text string throught textr transformer
 * @param  {String} text Text that will be processed
 * @param  {Array}  tfs  Array of transformers
 * @return {Void}        Write into strout or file and exit
 */
const render = (text, tfs = [], locale = 'en-us') => {
  const res = (textr({ locale }).use.apply(null, tfs))(text);
  if (cli.flags.outFile) {
    try {
      fs.writeFileSync(cwd(cli.flags.outFile), res, 'utf8');
    } catch (e) {
      console.error(`Something went wrong: ${e.message}`);
      process.exit(1);
    }
  } else {
    process.stdout.write(res);
    process.exit(0);
  }
};

/**
 * Get array of transformers.
 * If list of transformers is a string, then split it.
 * After all, require everything.
 * @param  {String|Array} t String or Array that contains list of transformers
 * @return {Array}          Return array of transform functions
 */
const tfs = (t = cli.flags.transforms) =>
  (typeof t === 'string' ? t.split(',') : t).map(tf => require(tf));

/**
 * Entry point
 */
if (cli.input[0]) {
  // If there is first argument, then read this file
  try {
    render(
      fs.readFileSync(cwd(cli.input[0])).toString(),
      tfs(),
      cli.flags.locale
    );
  } catch (e) {
    console.error(`Something went wrong: ${e.message}`);
    process.exit(1);
  }
} else {
  // If there's no first argument, then try to read stdin
  stdin()
    .then(str => render(str, tfs(), cli.flags.locale))
    .catch(err => err);
}

@@ -71,16 +71,49 @@
 stdin';%0A
+import watcher  from 'chokidar';%0A
 import t
@@ -707,16 +707,69 @@
 efault)%0A
+    -w, --watch         Watch changes in source file%0A
     -h, 
@@ -1172,24 +1172,42 @@
 : 'locale',%0A
+      w: 'watch',%0A
       h: 'he
@@ -1500,16 +1500,18 @@
 g%7D text 
+  
 Text tha
@@ -1555,16 +1555,18 @@
 %7D  tfs  
+  
 Array of
@@ -1571,32 +1571,80 @@
 of transformers%0A
+ * @param  %7BString%7D output File to write output%0A
  * @return %7BVoid
@@ -1644,16 +1644,18 @@
 n %7BVoid%7D
+  
         
@@ -1741,16 +1741,24 @@
  'en-us'
+, output
 ) =%3E %7B%0A 
@@ -1824,33 +1824,22 @@
 ;%0A  if (
-cli.flags.outFile
+output
 ) %7B%0A    
@@ -1875,25 +1875,14 @@
 cwd(
-cli.flags.outFile
+output
 ), r
@@ -2549,16 +2549,94 @@
 is file%0A
+  const args = %5B%0A    tfs(),%0A    cli.flags.locale,%0A    cli.flags.outFile%0A  %5D;%0A%0A
   try %7B%0A
@@ -2646,23 +2646,16 @@
  render(
-%0A      
 fs.readF
@@ -2662,20 +2662,16 @@
 ileSync(
-cwd(
 cli.inpu
@@ -2678,65 +2678,299 @@
 t%5B0%5D
-)).toString(),%0A      tfs(),%0A      cli.flags.locale%0A    );
+, 'utf8'), ...args);%0A    if (cli.flags.watch) %7B%0A      console.log(%60Watching $%7Bcli.input%5B0%5D%7D...%60);%0A      watcher.watch(cli.input%5B0%5D)%0A        .on('change', path =%3E %7B%0A          console.log(%60$%7Bpath%7D has been changed.%60);%0A          render(fs.readFileSync(path, 'utf8'), ...args);%0A        %7D);%0A    %7D
 %0A  %7D

Add --watch and -w flags.