#!/usr/bin/env node

const fs = require("fs");
const path = require("path");
const {transform} = require("babel-core");
const Table = require("cli-table");
const zlib = require("zlib");

run(process.argv[2]);

function run(inputFile) {
  const input = fs.readFileSync(inputFile).toString();
  const table = new Table(Object.assign({
    head: [
      "name",
      "output(bytes)",
      "output gzip(bytes)",
      "raw compression (%)",
      "gzip win (%)",
      "gzip % (%)"
    ],
  }, tableStyle()));

  const baseOutput = transform(input, {
    minified: true,
    compact: true,
    comments: false,
  }).code;

  const baseGzip = zlib.gzipSync(baseOutput);

  getPlugins().forEach(({name, plugin}) => {
    const output = transform(baseOutput, {
      plugins: [plugin],
      minified: true,
      compact: true,
      comments: false,
    }).code;

    const gzippedOutput = zlib.gzipSync(output);

    const percentage = (1 - len(output) / len(baseOutput)) * 100;
    const gzipWin = (1 - len(gzippedOutput) / len(baseGzip)) * 100;
    const gzipPercentage = (1 - len(gzippedOutput) / len(output)) * 100;

    table.push([
      name.split("babel-plugin-")[1],
      len(output),
      len(gzippedOutput),
      percentage.toFixed(3),
      gzipWin.toFixed(3),
      gzipPercentage.toFixed(3),
    ]);
  });

  const wcWin = (1 - len(baseOutput) / len(input)) * 100;

  console.log(`
input: input file with white space and comments removed

input size (bytes)      : ${len(baseOutput)}
input gzip size (bytes) : ${len(baseGzip)}

raw compression : % decrease from input -> output
gzip win        : % decrease from gzipInput -> gzipOutput
gzip %          : % decrease from output -> gzipOutput

Whitespaces and comments win (raw compression): ${wcWin}
`);

  console.log(table.toString());
}

function getPlugins() {
  return fs.readdirSync(path.join(__dirname, "../packages"))
    .filter((dir) => {
      if (!isDir(path.join(__dirname, "../packages", dir))) return false;
      if (dir.indexOf("babel-plugin-") !== 0) return false;
      try {
        require(`../packages/${dir}`);
        return true;
      } catch (e) {
        return false;
      }
    })
    .map((pluginName) => ({
      name: pluginName,
      plugin: require(`../packages/${pluginName}`)
    }));
}

function isDir(p) {
  try {
    return fs.statSync(p).isDirectory();
  } catch (e) {
    return false;
  }
}

function len(str) {
  return Buffer.byteLength(str, "utf-8");
}

// just to keep it at the bottom
function tableStyle() {
  return {
    chars: {
      top: "",
      "top-mid": "" ,
      "top-left": "" ,
      "top-right": "",
      bottom: "" ,
      "bottom-mid": "" ,
      "bottom-left": "" ,
      "bottom-right": "",
      left: "",
      "left-mid": "",
      mid: "",
      "mid-mid": "",
      right: "" ,
      "right-mid": "",
      middle: " ",
    },
    style: {
      "padding-left": 0,
      "padding-right": 0,
      head: ["bold"],
    }
  };
}

@@ -178,16 +178,74 @@
 %22zlib%22);
+%0Aconst chalk = require('chalk');%0Aconst vm = require('vm');
 %0A%0Arun(pr
@@ -530,16 +530,43 @@
 p %25 (%25)%22
+,%0A      %22parse time %CE%94 (ms)%22
 %0A    %5D,%0A
@@ -746,16 +746,67 @@
 tput);%0A%0A
+  const baseParseTime = getParseTime(baseOutput);%0A%0A
   getPlu
@@ -1040,16 +1040,61 @@
 tput);%0A%0A
+    const parseTime = getParseTime(output);%0A%0A
     cons
@@ -1293,16 +1293,70 @@
 * 100;%0A%0A
+    const parseTimeDiff = baseParseTime - parseTime;%0A%0A
     tabl
@@ -1531,24 +1531,89 @@
 toFixed(3),%0A
+      chalk%5BparseTimeDiff %3C 0 ? 'green' : 'red'%5D(parseTimeDiff),%0A
     %5D);%0A  %7D)
@@ -2572,16 +2572,16 @@
 Name%7D%60)%0A
-
     %7D));
@@ -2580,24 +2580,341 @@
     %7D));%0A%7D%0A%0A
+function getParseTime(code) %7B%0A  // const context = vm.createContext();%0A  // const script = new vm.Script(code);%0A%0A  const parseStart = process.hrtime();%0A  new Function(code + ';void(' + Math.random() + ');');%0A  // script.runInContext(context);%0A  const diff = process.hrtime(parseStart);%0A  return diff%5B1%5D / 1000000;%0A%7D%0A%0A
 function isD

Add parse times to comparison script