#!/usr/bin/env node
const { spawnSync } = require('node:child_process')
const { arch, constants } = require('node:os')
const path = require('node:path')

const WRAPPER_NAME = require('./package.json').name
const PLATFORMS = {
	'darwin-arm64': { pkg: '@ampcode/cli-darwin-arm64', bin: 'amp' },
	'darwin-x64': { pkg: '@ampcode/cli-darwin-x64', bin: 'amp' },
	'linux-arm64': { pkg: '@ampcode/cli-linux-arm64', bin: 'amp' },
	'linux-x64': { pkg: '@ampcode/cli-linux-x64', bin: 'amp' },
	'win32-x64': { pkg: '@ampcode/cli-win32-x64', bin: 'amp.exe' },
}

function printHelp() {
	console.error('  For help, visit https://ampcode.com/manual or email amp-devs@ampcode.com.')
}

function detectMusl() {
	if (process.platform !== 'linux') {
		return false
	}
	const report = typeof process.report?.getReport === 'function' ? process.report.getReport() : null
	return report != null && report.header?.glibcVersionRuntime === undefined
}

function getPlatformKey() {
	let cpu = arch()
	if (process.platform === 'linux') {
		return 'linux-' + cpu + (detectMusl() ? '-musl' : '')
	}
	if (process.platform === 'darwin' && cpu === 'x64') {
		const result = spawnSync('sysctl', ['-n', 'sysctl.proc_translated'], { encoding: 'utf8' })
		if (result.stdout?.trim() === '1') {
			cpu = 'arm64'
		}
	}
	return process.platform + '-' + cpu
}

function getBinaryPath() {
	const platformKey = getPlatformKey()
	const info = PLATFORMS[platformKey]
	if (!info) {
		console.error(`[${WRAPPER_NAME}] Unsupported platform: ${process.platform} ${arch()}. Supported: ${Object.keys(PLATFORMS).join(', ')}`)
		printHelp()
		process.exit(1)
	}
	try {
		const pkgDir = path.dirname(require.resolve(info.pkg + '/package.json'))
		return path.join(pkgDir, info.bin)
	} catch {
		console.error(`[${WRAPPER_NAME}] Could not find native binary package "${info.pkg}".`)
		console.error('  Try reinstalling without --ignore-scripts / --omit=optional.')
		printHelp()
		process.exit(1)
	}
}

function main() {
	const binaryPath = getBinaryPath()
	const result = spawnSync(binaryPath, process.argv.slice(2), {
		stdio: 'inherit',
		env: process.env,
	})
	if (result.error) {
		console.error(`[${WRAPPER_NAME}] Failed to execute native binary at ${binaryPath}`)
		console.error('  ' + result.error.message)
		printHelp()
		process.exit(1)
	}
	if (result.signal) {
		const signum = constants.signals[result.signal] ?? 0
		process.exit(128 + signum)
	}
	process.exit(result.status ?? 1)
}

main()
