import { spawn } from 'node:child_process'
import { cp, mkdir } from 'node:fs/promises'
import { existsSync } from 'node:fs'
import path from 'node:path'
import process from 'node:process'

const projectRoot = process.cwd()
const standaloneRoot = path.join(projectRoot, '.next', 'standalone')
const standaloneNextRoot = path.join(standaloneRoot, '.next')

function resolveStandaloneServer() {
  const directServer = path.join(standaloneRoot, 'server.js')
  if (existsSync(directServer)) {
    return { serverPath: directServer, appRoot: standaloneRoot }
  }

  const nestedServer = path.join(standaloneRoot, 'explorer-monorepo', 'frontend', 'server.js')
  if (existsSync(nestedServer)) {
    return { serverPath: nestedServer, appRoot: path.dirname(nestedServer) }
  }

  return { serverPath: directServer, appRoot: standaloneRoot }
}

async function copyIfPresent(sourcePath, destinationPath) {
  if (!existsSync(sourcePath)) {
    return
  }

  await mkdir(path.dirname(destinationPath), { recursive: true })
  await cp(sourcePath, destinationPath, { recursive: true, force: true })
}

async function main() {
  const { serverPath, appRoot } = resolveStandaloneServer()
  if (!existsSync(serverPath)) {
    console.error('Standalone server build is missing. Run `npm run build` first.')
    process.exit(1)
  }

  await copyIfPresent(path.join(projectRoot, '.next', 'static'), path.join(standaloneNextRoot, 'static'))
  await copyIfPresent(path.join(projectRoot, 'public'), path.join(appRoot, 'public'))

  const child = spawn(process.execPath, [serverPath], {
    stdio: 'inherit',
    env: process.env,
  })

  child.on('exit', (code, signal) => {
    if (signal) {
      process.kill(process.pid, signal)
      return
    }
    process.exit(code ?? 0)
  })
}

main().catch((error) => {
  console.error(error)
  process.exit(1)
})
