// @ts-expect-error Vite config executes in Node; the application tsconfig intentionally excludes Node globals.
import { readFile, writeFile } from 'node:fs/promises'
// @ts-expect-error Vite config executes in Node; the application tsconfig intentionally excludes Node globals.
import { resolve } from 'node:path'
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

declare const process: { cwd(): string }

const securityHeaders = {
  'Cross-Origin-Opener-Policy': 'same-origin',
  'Cross-Origin-Embedder-Policy': 'require-corp',
  'Cross-Origin-Resource-Policy': 'same-origin',
  'Content-Security-Policy': "default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; worker-src 'self' blob:; connect-src 'self'; img-src 'self' data: blob:; font-src 'self' data:; object-src 'none'; base-uri 'self'; frame-ancestors 'none'",
  'Permissions-Policy': 'camera=(), microphone=(), geolocation=(), payment=()',
}

const serviceWorkerPrecachePlugin = () => ({
  name: 'bitbybit-service-worker-precache',
  async writeBundle(options: { dir?: string }, bundle: Record<string, unknown>) {
    const outputDirectory = options.dir ?? resolve(process.cwd(), 'dist')
    const shell = ['/', '/index.html', '/manifest.webmanifest', '/vendor/camotics/camotics-sweep.wasm', ...Object.keys(bundle).filter((fileName) => fileName.startsWith('assets/')).map((fileName) => `/${fileName}`)]
    const templatePath = resolve(process.cwd(), 'public/sw.js')
    const outputPath = resolve(outputDirectory, 'sw.js')
    const template = await readFile(templatePath, 'utf8')
    const generated = template.replace(/const SHELL = \[[^\n]*\]/, `const SHELL = ${JSON.stringify([...new Set(shell)])}`)
    await writeFile(outputPath, generated)
  },
})

export default defineConfig({
  plugins: [react(), serviceWorkerPrecachePlugin()],
  server: {
    port: 5173,
    strictPort: false,
    proxy: {
      '/linuxcnc-machine': {
        target: 'https://localhost:5190',
        changeOrigin: true,
        secure: false,
        rewrite: (path: string) => path.replace(/^\/linuxcnc-machine/, ''),
      },
    },
    headers: {
      'Cross-Origin-Opener-Policy': 'same-origin',
      'Cross-Origin-Embedder-Policy': 'require-corp',
    },
    watch: {
      ignored: ['**/.cache/**', '**/.runtime/**', '**/cnc_wams_gpt6/**', '**/CAMotics/**', '**/OpenCAMLib/**'],
    },
  },
  preview: {
    headers: securityHeaders,
  },
  optimizeDeps: {
    exclude: ['@sqlite.org/sqlite-wasm', '@bitbybit-dev/occt', '@bitbybit-dev/occt-worker'],
  },
  worker: {
    format: 'es',
  },
  build: {
    chunkSizeWarningLimit: 600,
    rollupOptions: {
      output: {
        manualChunks: {
          three: ['three'],
        },
      },
    },
  },
})
