const esbuild = require("esbuild")
const fs = require("fs")
const path = require("path")

const config = require(process.cwd() + (process.argv?.length > 3 ? "/" + process.argv[3] : "/esbuild.config.js"))
const { watch } = require("chokidar")

function log(str, clear) {
    if (clear) {
        if (process.stdout.cursorTo && process.stdout.clearScreenDown) {
            process.stdout.cursorTo(0, 0)
            process.stdout.clearScreenDown()
        }
    }
    console.log("\x1b[36m%s\x1b[0m", str)
}

let buildResults

async function build(catchError) {
    log((buildResults ? "re" : "") + "building...")
    const timerStart = Date.now()
    try {
        buildResults = buildResults ? await buildResults.rebuild() : await esbuild.build(config.options)
        if (config.options.metafile) {
            fs.writeFileSync(
                path.dirname(config.options.outfile) + "/meta.json",
                JSON.stringify(buildResults.metafile, null, 4)
            )
        }
    } catch (e) {
        console.log(e)
        if (!catchError) throw e
    }

    const timerEnd = Date.now()
    log(`built in ${timerEnd - timerStart}ms.`)
}

let bs
switch (process.argv?.length > 2 ? process.argv[2] : "build") {
    case "serve":
        console.log("\x1b[36m%s\x1b[0mserving...")
        esbuild.serve(config.serve, config.options).catch((err) => {
            console.error(err)
            process.exit(1)
        })
        break
    case "start":
        bs = require("browser-sync")
        bs.init(config.browserSync)
    case "watch":
        config.options.incremental = true
        build(true)
        const watcher = watch(config.watch.path)
        log("watching files...")
        watcher.on("change", function (path) {
            log(`${path} changed`, true)
            build(true).then(() => {
                if (bs) {
                    bs.reload()
                }
            })
        })
        break
    default:
        build()
}
