module.exports = function (grunt) {
    "use strict";

    grunt.initConfig({
        clean: ["./dist", "./tmp"],
        copy: {
            build: {
                files: [{
                    expand: true,
                    cwd: "./src",
                    src: ["**/license*", "**/*.lua", "**/*.cfg"],
                    dest: "dist/",
                    filter: 'isFile'
                }]
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks("grunt-contrib-copy");
    grunt.loadNpmTasks('grunt-file-append');
    grunt.loadNpmTasks('grunt-exec');

    grunt.registerTask("compile-moonscript", "compiles moonscript files to lua", function() {
        grunt.file.expand({filter: 'isDirectory'}, "src/**").forEach(function (dir) {
            grunt.file.expand({filter: 'isFile'}, dir + "/*.moon").forEach(function (file) {
                const directory = file.substr(0, file.lastIndexOf('/') + 1).replace("src/","");
                const file_name = file.substr(file.lastIndexOf('/') + 1);
                const file_name_sans_ext = file_name.substr(0, file_name.lastIndexOf('.'));
                const output_path = "dist/" + directory + file_name_sans_ext + '.lua';

                const exec_task = grunt.config.get('exec') || {};
                exec_task[file] = {
                    command: "moonc -o " + output_path + " " + file
                }

                console.log("Added exec task: moonc -o " + output_path + " " + file)

                grunt.config.set('exec', exec_task);
            });
        });
    });

    grunt.registerTask("minify-lua-modules", "minifies lua modules", function () {
        const fs = require('fs');
        const luamin = require('luamin');
        const util = require('util');
        grunt.file.expand({filter: 'isDirectory'}, "dist/**").forEach(function (dir) {
            grunt.file.expand({filter: 'isFile'}, dir + "/*.lua").forEach(function (file) {
                const directory = file.substr(0, file.lastIndexOf('/'));
                const file_name = file.substr(file.lastIndexOf('/') + 1);
                const file_name_sans_ext = file_name.substr(0, file_name.lastIndexOf('.'));

                const lua = fs.readFileSync(file, 'utf8');
                const minified_contents = luamin.minify(lua);

                const minified_file_name = file_name_sans_ext + '.min.lua';
                const minified_file = directory + '/' + minified_file_name;
                fs.writeFileSync(minified_file, minified_contents);
                const file_stats = fs.statSync(file);
                const minified_file_stats = fs.statSync(minified_file);
                const saved_space = file_stats.size - minified_file_stats.size;
                const saved_space_percent = (100 * (1 - minified_file_stats.size / file_stats.size)).toFixed(2);
                console.log(util.format("Minified: %s: %f KB -> %s: %f KB. SAVED %d%% %d KB", file_name, file_stats.size / 1000, minified_file_name, minified_file_stats.size / 1000, saved_space_percent, saved_space / 1000));
            });
        });
    });

    grunt.registerTask("build-spm-bootstrap", "Make sure a single bootstrap file exists for SPM", function () {
        const fs = require('fs');
        grunt.file.expand({filter: 'isFile'}, "dist/**/bootstrap.min.lua").forEach(function (minified_file) {
            const directory = minified_file.substr(0, minified_file.lastIndexOf('/'));
            const minified_contents = fs.readFileSync(minified_file, 'utf8');
            fs.writeFileSync(directory + '/bootstrap.lua', minified_contents);
            fs.unlinkSync(minified_file);
            console.log("Removed unminified bootstrap file: " + directory + '/bootstrap.lua')
        });
    });

    grunt.registerTask("default", [
        "clean",
        "copy",
        "compile-moonscript",
        "exec",
        "minify-lua-modules",
        "build-spm-bootstrap"
    ]);
};