import {
	readFileSync,
	writeFileSync,
	existsSync,
	readdirSync,
	copyFileSync,
	rmSync,
	unlinkSync
} from 'fs';
import { resolve } from 'path';
import type { Plugin } from 'vite';
import * as fflate from 'fflate';

const GUIDE_FOR_FRONTEND = `
<!--
  This is a static build of the frontend.
  It is automatically generated by the build process.
  Do not edit this file directly.
  To make changes, refer to the "Web UI" section in the README.
-->
`.trim();

const OUTPUT_DIR = process.env.LLAMA_UI_OUT_DIR ?? './dist';
const MAX_BUNDLE_SIZE = 3 * 1024 * 1024;

export function llamaCppBuildPlugin() {
	return {
		name: 'llamacpp:build',
		apply: 'build' as const,
		closeBundle() {
			// Ensure the SvelteKit adapter has finished writing to ../public
			setTimeout(() => {
				try {
					const indexPath = resolve('../public_llamacpp/index_llamacpp.html');
					const gzipPath = resolve('../public_llamacpp/index_llamacpp.html.gz');

					if (!existsSync(indexPath)) {
						return;
					}

					let content = readFileSync(indexPath, 'utf-8');

					const faviconPath = resolve('static/favicon.svg');
					if (existsSync(faviconPath)) {
						const faviconContent = readFileSync(faviconPath, 'utf-8');
						const faviconBase64 = Buffer.from(faviconContent).toString('base64');
						const faviconDataUrl = `data:image/svg+xml;base64,${faviconBase64}`;

						content = content.replace(/href="[^"]*favicon\.svg"/g, `href="${faviconDataUrl}"`);

						console.log('✓ Inlined favicon.svg as base64 data URL');
					}

					content = content.replace(/\r/g, '');
					content = GUIDE_FOR_FRONTEND + '\n' + content;

					const compressed = fflate.gzipSync(Buffer.from(content, 'utf-8'), { level: 9 });

					compressed[0x4] = 0;
					compressed[0x5] = 0;
					compressed[0x6] = 0;
					compressed[0x7] = 0;
					compressed[0x9] = 0;

					if (compressed.byteLength > MAX_BUNDLE_SIZE) {
						throw new Error(
							`Bundle size is too large (${Math.ceil(compressed.byteLength / 1024)} KB).\n` +
								`Please reduce the size of the frontend or increase MAX_BUNDLE_SIZE in vite.config.ts.\n`
						);
					}

					writeFileSync(gzipPath, compressed);
					console.log('✓ Created index_llamacpp.html.gz');
				} catch (error) {
					console.error('Failed to create gzip file:', error);
				}
			}, 100);
		}
	};
}
