#!/bin/sh
set -e

for pkg in packages/*; do
    if [ -d "$pkg/src" ]; then
        echo "Preparing and building $pkg..."
        node -e '
            const fs = require("fs");
            const pkgPath = process.argv[1];
            const file = pkgPath + "/tsconfig.json";

            let config = {
                compilerOptions: {
                    ignoreDeprecations: "6.0",
                    noImplicitAny: false,
                    skipLibCheck: true,
                    strict: false,
                    target: "es2019",
                    module: "esnext",
                    jsx: "react",
                    experimentalDecorators: true,
                    lib: ["es2019", "dom"],
                    types: ["node"],
                    rootDir: "src",
                    outDir: "dist",
                    declaration: true
                },
                include: ["src"]
            };

            fs.writeFileSync(file, JSON.stringify(config, null, 2));

            if (fs.existsSync("LICENSE") && !fs.existsSync(pkgPath + "/LICENSE")) {
                fs.copyFileSync("LICENSE", pkgPath + "/LICENSE");
            }

            const srcDir = pkgPath + "/src";
            function walk(dir) {
                fs.readdirSync(dir, { withFileTypes: true }).forEach(entry => {
                    const full = dir + "/" + entry.name;
                    if (entry.isDirectory()) walk(full);
                    else if (entry.isFile()) {
                        if (entry.name.includes(".test.") || entry.name.includes(".spec.")) {
                            fs.unlinkSync(full);
                            return;
                        }
                        if (entry.name.endsWith(".ts") || entry.name.endsWith(".tsx")) {
                            let content = fs.readFileSync(full, "utf8");
                            content = content.replace(/PluginObj/g, "PluginObject");
                            content = content.replace(/^\/\/\@ts-nocheck\n/, "");
                            if (content.startsWith("#!")) {
                                let idx = content.indexOf("\n");
                                content = content.slice(0, idx + 1) + "//@ts-nocheck\n" + content.slice(idx + 1);
                            } else if (!content.startsWith("//@ts-nocheck")) {
                                content = "//@ts-nocheck\n" + content;
                            }
                            fs.writeFileSync(full, content);
                        }
                    }
                });
            }
            walk(srcDir);
        ' "$pkg"

        tsc --project "$pkg/tsconfig.json" --skipLibCheck

        node -e '
            const fs = require("fs");
            const path = require("path");
            const pkgPath = process.argv[1];
            const distDir = path.join(pkgPath, "dist");

            function fixRelativeImports(dir) {
                if (!fs.existsSync(dir)) return;
                fs.readdirSync(dir, { withFileTypes: true }).forEach(entry => {
                    const fullPath = path.join(dir, entry.name);
                    if (entry.isDirectory()) {
                        fixRelativeImports(fullPath);
                    } else if (entry.isFile() && entry.name.endsWith(".js")) {
                        let code = fs.readFileSync(fullPath, "utf8");
                        code = code.replace(/(from\s+["\x27](\.\.?\/[^"\x27]+?))(["\x27])/g, (match, prefix, pathStr, quote) => {
                            if (!pathStr.endsWith(".js") && !pathStr.endsWith(".json")) {
                                return prefix + ".js" + quote;
                            }
                            return match;
                        });
                        fs.writeFileSync(fullPath, code);
                    }
                });
            }
            fixRelativeImports(distDir);

            const pkgJsonPath = path.join(pkgPath, "package.json");
            if (fs.existsSync(pkgJsonPath)) {
                let content = fs.readFileSync(pkgJsonPath, "utf8");
                let pkg = JSON.parse(content);
                if (pkg.main) pkg.main = pkg.main.replace(/\.cjs$/, ".js").replace(/\.mjs$/, ".js");
                if (pkg.module) pkg.module = pkg.module.replace(/\.mjs$/, ".js").replace(/\.cjs$/, ".js");
                if (pkg.types) pkg.types = pkg.types.replace(/\.d\.mts$/, ".d.ts");
                if (pkg.exports) delete pkg.exports;
                fs.writeFileSync(pkgJsonPath, JSON.stringify(pkg, null, 2));
            }
        ' "$pkg"
    fi
done
