var fs = require("fs");
var path = require("path");

var libdir = path.dirname(process.argv[1]);
var libmod = libdir + (fs.existsSync(libdir + "/node_modules") ? "/node_modules" : "/..");
var command = process.argv[2];
var context = process.argv[3] && path.resolve(process.argv[3]);

// Print version
var version = JSON.parse(fs.readFileSync(libdir + "/package.json")).version;
console.log("Version: inferno-beaker " + version + "\n");

// Validate arguments
if (!command || !context || ["watch", "build"].indexOf(command) < 0) {
    help();
    process.exit(1);
}

// Find all JavaScript entries
var entry = {};
var entriesDir = context + "/js/entries/";
try {
    fs.readdirSync(entriesDir).forEach(function(filename) {
        if (/.*\.sw.$/.test(filename) === false) {
            entry[filename.replace(/\.[^\.]+$/, "")] = entriesDir + filename;
        }
    });
} catch (_) {
    console.log("Directory js/entries/ not found");
}

// Find all HTML files
try {
    var pages = fs.readdirSync(context + "/html").filter(function(filename) {
        return /.*\.sw.$/.test(filename) === false;
    });
} catch (_) {
    console.log("Directory html/ not found");
    var pages = [];
}

// Choose options
var options = {};
switch (command) {
    case "watch":
        options = {
            "NODE_ENV": '"development"',
            "filename": "[name].min.js",
            "minimize": false,
            "sourceMap": true,
        };
        break;
    case "build":
        options = {
            "NODE_ENV": '"production"',
            "filename": "[name].min.js",
            "minimize": true,
            "sourceMap": false,
        };
        break;
}

var webpack = require(libmod + "/webpack");
var HtmlWebpackPlugin = require(libmod + "/html-webpack-plugin");
var autoprefixer = require(libmod + "/autoprefixer");

var compiler = webpack({
    devtool: options.sourceMap && "inline-source-map",
    context: context,
    resolve: {
        extensions: ["", ".js", ".ls", ".ts", ".tsx"],
    },
    externals: {
        "inferno": "Inferno",
        "inferno-component": "InfernoComponent",
        "inferno-create-class": "InfernoCreateClass",
        "inferno-create-element": "InfernoCreateElement",
        "react": "React",
        "react-dom": "ReactDOM",
    },
    resolveLoader: {
        modulesDirectories: [libmod]
    },
    entry: entry,
    output: {
        path: context + "/dist",
        filename: options.filename,
    },
    module: {
        loaders: [{
            test: /\.tsx?$/,
            exclude: /node_modules/,
            loader: "ts-loader"
        }, {
            test: /\.ls$/,
            exclude: /node_modules/,
            loader: "livescript-loader"
        }, {
            test: /^[^!]+.css$/,
            loader: "style!css?-minimize!postcss",
        }, {
            test: /^[^!]+.less$/,
            loader: "style!css?-minimize!postcss!less",
        }]
    },
    ts: {
        compilerOptions: {
            "jsx": "react",
            "module": "commonjs",
            "target": "es5",
            "typeRoots": [
                libdir + "/@types",
                context + "/node_modules/@types",
                context + "/js/@types",
            ],
            "lib": ["dom", "es2015"],
        }
    },
    plugins: pages.map(function(filename) {
        return new HtmlWebpackPlugin({
            filename: filename,
            template: context + "/html/" + filename,
        });
    }).concat(options.minimize ? [
        new webpack.optimize.UglifyJsPlugin({
            minimize: true
        })
    ] : []).concat([
        new webpack.DefinePlugin({
            "process.env": {
                NODE_ENV: options.NODE_ENV
            }
        })
    ]),
    postcss: function() {
        return [
            autoprefixer({
                browsers: ["last 2 versions", "Safari >= 8"]
            })
        ];
    }
});

function buildToolkit() {
    webpack({
        context: libdir,
        entry: libdir + "/inferno-toolkit.js",
        output: {
            path: context + "/dist",
            filename: "inferno-toolkit.min.js",
        },
        plugins: [
            new webpack.optimize.UglifyJsPlugin({
                minimize: true
            }),
            new webpack.DefinePlugin({
                "process.env": {
                    NODE_ENV: '"production"'
                }
            })
        ]
    }).run(function() {});
}

function watch() {
    buildToolkit();
    compiler.watch({
        poll: true
    }, function(err, stats) {
        console.log(stats.toString({
            colors: true
        }));
    });
}

function build() {
    buildToolkit();
    compiler.run(function(err, stats) {
        console.log(stats.toString({
            colors: true
        }));
        if (stats.hasErrors()) process.exit(2);
    });
}

function help() {
    console.error("Usage:");
    console.error("  inferno-beaker watch <source dir>");
    console.error("  inferno-beaker build <source dir>");
}

if (command === "watch") watch();
if (command === "build") build();

@@ -1654,16 +1654,432 @@
 eak;%0A%7D%0A%0A
+// Generate tsconfig.json%0Avar tsconfig = %7B%0A    compilerOptions: %7B%0A        %22jsx%22: %22react%22,%0A        %22module%22: %22commonjs%22,%0A        %22target%22: %22es5%22,%0A        %22typeRoots%22: %5B%0A            libdir + %22/@types%22,%0A            context + %22/node_modules/@types%22,%0A            context + %22/js/@types%22,%0A        %5D,%0A        %22lib%22: %5B%22dom%22, %22es2015%22%5D,%0A    %7D%0A%7D%0Afs.writeFileSync(context + %22/tsconfig.json%22, JSON.stringify(tsconfig, null, 2))%0A%0A
 var webp
@@ -3332,359 +3332,8 @@
  %7D,%0A
-    ts: %7B%0A        compilerOptions: %7B%0A            %22jsx%22: %22react%22,%0A            %22module%22: %22commonjs%22,%0A            %22target%22: %22es5%22,%0A            %22typeRoots%22: %5B%0A                libdir + %22/@types%22,%0A                context + %22/node_modules/@types%22,%0A                context + %22/js/@types%22,%0A            %5D,%0A            %22lib%22: %5B%22dom%22, %22es2015%22%5D,%0A        %7D%0A    %7D,%0A
     

Upgrade typescript to 2.1.x