import { sveltekit } from "@sveltejs/kit/vite";
import { defineConfig, loadEnv } from "vite";
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";

const pkg = JSON.parse(
	readFileSync(
		fileURLToPath(new URL("./package.json", import.meta.url)),
		"utf8",
	),
) as { version: string };

// Parse the VITE_DEV_HOST override into the shape `server.host`
// expects. `""` / `"false"` keeps Vite's safe default (loopback
// only); `"true"` / `"1"` flips to "all interfaces" (`0.0.0.0` plus
// IPv6); any other string is passed through verbatim so a developer
// can pin a single LAN address (e.g. `"192.168.1.5"`). Returning
// `undefined` lets Vite stay on its built-in default.
function parseDevHost(raw: string | undefined): string | boolean | undefined {
	if (raw === undefined || raw === "") return undefined;
	const normalised = raw.toLowerCase();
	if (normalised === "true" || normalised === "1" || normalised === "yes") {
		return true;
	}
	if (normalised === "false" || normalised === "0" || normalised === "no") {
		return false;
	}
	return raw;
}

export default defineConfig(({ mode }) => {
	// `loadEnv("", ...)` matches every `.env*` entry regardless of
	// the customary `VITE_` prefix so the config sees the same view
	// that client code sees via `import.meta.env`. Without this
	// `process.env` would carry only the shell's exports, and
	// per-developer files like `.env.development.local` would
	// silently miss the config — every override would have to be
	// passed on the `pnpm dev` command line.
	const env = loadEnv(mode, process.cwd(), "");

	// Default upstream gateway addresses used by the dev proxy.
	// Override by pointing `VITE_DEV_PROXY_TARGET` (REST surface)
	// and `VITE_DEV_GRPC_PROXY_TARGET` (Connect-Web surface) at a
	// different gateway when working with a remote stack instead of
	// `tools/local-dev/`. In production the two surfaces sit behind
	// a single host; the split here exists only because local-dev
	// runs the REST listener on :8080 and the authenticated
	// Connect-Web listener on :9090.
	const DEV_PROXY_TARGET =
		env.VITE_DEV_PROXY_TARGET || "http://localhost:8080";
	const DEV_GRPC_PROXY_TARGET =
		env.VITE_DEV_GRPC_PROXY_TARGET || "http://localhost:9090";

	// `VITE_DEV_HOST` opts the dev server into wider listener
	// binding. Default stays at Vite's safe loopback-only behaviour
	// so an unattended `pnpm dev` on someone's laptop never exposes
	// the unauthenticated dev surface to the LAN by accident. Set
	// the value in `.env.development.local` (untracked) when
	// reaching the server through SSH port forwarding, a VM, or a
	// container needs a non-loopback bind.
	const devHost = parseDevHost(env.VITE_DEV_HOST);

	return {
		plugins: [sveltekit()],
		define: {
			__APP_VERSION__: JSON.stringify(pkg.version),
		},
		server: {
			...(devHost !== undefined ? { host: devHost } : {}),
			// Same-origin proxy so the browser sees only
			// `localhost:5173` and never trips a cross-origin
			// preflight against the gateway's REST + Connect-Web
			// surfaces. Production deployments serve the UI and the
			// gateway behind a single host, so the proxy is purely a
			// dev-time convenience.
			proxy: {
				"/api": {
					target: DEV_PROXY_TARGET,
					changeOrigin: false,
				},
				"/galaxy.gateway.v1.EdgeGateway": {
					target: DEV_GRPC_PROXY_TARGET,
					changeOrigin: false,
					// Connect-Web server-streaming
					// (`SubscribeEvents`) uses chunked HTTP
					// responses; http-proxy passes them through
					// transparently as long as buffering stays off,
					// which is the default.
				},
			},
		},
	};
});
