"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
// native
const node_fs_1 = require("node:fs");
const node_path_1 = require("node:path");
const node_stream_1 = require("node:stream");
// lib
const decompress_1 = __importDefault(require("decompress"));
const shelljs_1 = __importDefault(require("shelljs"));
const tar_1 = __importDefault(require("tar"));
// src
const module_specific_js_1 = require("./module-specific.js");
const version = (0, module_specific_js_1.getVersion)();
const _dirname = (0, module_specific_js_1.getDirname)();
const releaseRepoUrl = "https://github.com/tablelandnetwork/go-tableland";
// These must match the builds that go-tableland is automating
const platarchs = [
    {
        name: "darwin-amd64",
        filetype: ".tar.gz",
    },
    {
        name: "darwin-arm64",
        filetype: ".tar.gz",
    },
    {
        name: "linux-amd64",
        filetype: ".tar.gz",
    },
    {
        name: "linux-arm64",
        filetype: ".tar.gz",
    },
    {
        name: "windows-amd64",
        filetype: ".zip",
    },
];
const binDirectory = (0, node_path_1.join)(_dirname, "..", "..", "bin");
const go = async function () {
    console.log(`installing validator binaries: ${platarchs
        .map((pa) => `${pa.name}${pa.filetype}`)
        // eslint-disable-next-line
        .join(", ")} for version: ${version}`);
    for (let i = 0; i < platarchs.length; i++) {
        try {
            await fetchAndUnpack(platarchs[i]);
        }
        catch (err) {
            // If the version of this package doesn't match a release there will not be anything to fetch,
            // but we don't want the build to totally fail in case someone wants to publish a custom build
            console.log("could not fetch:", platarchs[i]);
            console.log(err);
        }
    }
    console.log("done installing validator binaries");
};
const fetchAndUnpack = async function (platarch) {
    // eslint-disable-next-line
    const url = `${releaseRepoUrl}/releases/download/v${version}/api-${platarch.name}${platarch.filetype}`;
    console.log(`fetching: ${url}`);
    const res = await fetch(url);
    if (res.body === null)
        throw new Error("could not fetch release");
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment, @typescript-eslint/prefer-ts-expect-error
    // @ts-ignore node and web typings still don't work together, but this works correctly
    const downloadReadstream = node_stream_1.Readable.fromWeb(res.body);
    if (platarch.filetype === ".tar.gz") {
        await tarx(downloadReadstream);
    }
    if (platarch.filetype === ".zip") {
        await unzip(downloadReadstream);
    }
    // name windows executables correctly
    const filename = platarch.name.includes("windows")
        ? platarch.name + ".exe"
        : platarch.name;
    const binName = platarch.name.includes("windows") ? "api.exe" : "api";
    // all of the unzipped/extracted downloads expand to a single file named `api` except window, which is `api.exe`
    shelljs_1.default.mv((0, node_path_1.join)(binDirectory, binName), (0, node_path_1.join)(binDirectory, filename));
};
const tarx = async function (inputStream) {
    return await new Promise((resolve, reject) => {
        // We can pipe the fetch response straight to tar
        const sink = inputStream.pipe(tar_1.default.x({ C: binDirectory }));
        sink.on("finish", () => resolve());
        sink.on("error", (err) => reject(err));
    });
};
const unzip = async function (inputStream) {
    const tempFilename = (0, node_path_1.join)(binDirectory, "api-temp.zip");
    // download the zip file to a temp location
    await new Promise(function (resolve, reject) {
        const destination = (0, node_fs_1.createWriteStream)(tempFilename);
        const sink = inputStream.pipe(destination);
        sink.on("finish", () => resolve());
        sink.on("error", (err) => reject(err));
    });
    // unzip the tempfile, NOTE: this will reuslt in a bin named `api`
    await (0, decompress_1.default)(tempFilename, binDirectory);
    // remove the temp zip file now that it's content has been unzipped to `api`
    shelljs_1.default.rm(tempFilename);
};
go().catch(function (err) {
    console.error(err);
    process.exit(1);
});
