#!/usr/bin/env bun
import { $ } from "bun"
import pkg from "../package.json"
import { Script } from "@woozlit/script"
import { fileURLToPath } from "url"
import fs from "node:fs"

const dir = fileURLToPath(new URL("..", import.meta.url))
process.chdir(dir)

let otpVal = ""
const otpIdx = process.argv.indexOf("--otp")
if (otpIdx !== -1 && process.argv[otpIdx + 1]) {
  otpVal = process.argv[otpIdx + 1]
} else {
  const match = process.argv.find((arg) => arg.startsWith("--otp="))
  if (match) otpVal = match.split("=")[1]
}
async function published(name: string, version: string) {
  return (await $`npm view ${name}@${version} version`.nothrow()).exitCode === 0
}

async function publish(dir: string, name: string, version: string) {
  if (process.platform !== "win32") await $`chmod -R 755 .`.cwd(dir)
  if (await published(name, version)) {
    console.log(`already published ${name}@${version}`)
    return
  }
  if (otpVal) {
    await $`npm publish --access public --tag ${Script.channel} --otp ${otpVal}`.cwd(dir)
  } else {
    await $`npm publish --access public --tag ${Script.channel}`.cwd(dir)
  }
}

const binaries: Record<string, string> = {}
for (const filepath of new Bun.Glob("*/package.json").scanSync({ cwd: "./dist" })) {
  const pkgDist = await Bun.file(`./dist/${filepath}`).json()
  if (pkgDist.name !== pkg.name) {
    binaries[pkgDist.name] = pkgDist.version
  }
}
console.log("binaries", binaries)
const version = Object.values(binaries)[0] || pkg.version

const targetDir = `./dist/${pkg.name}`
fs.mkdirSync(targetDir, { recursive: true })
fs.cpSync("./bin", `${targetDir}/bin`, { recursive: true })
fs.cpSync("./script/postinstall.mjs", `${targetDir}/postinstall.mjs`)
const licensePath = fileURLToPath(new URL("../../../LICENSE", import.meta.url))
await Bun.file(`./dist/${pkg.name}/LICENSE`).write(await Bun.file(licensePath).text())

await Bun.file(`./dist/${pkg.name}/package.json`).write(
  JSON.stringify(
    {
      name: pkg.name,
      bin: {
        woozlit: "bin/woozlit",
      },
      scripts: {
        postinstall: "bun ./postinstall.mjs || node ./postinstall.mjs",
      },
      version: version,
      license: pkg.license,
      optionalDependencies: binaries,
    },
    null,
    2,
  ),
)

for (const [name, version] of Object.entries(binaries)) {
  await publish(`./dist/${name}`, name, version)
}
await publish(`./dist/${pkg.name}`, pkg.name, version)
