/**
 * SparkBun configuration type definitions
 * Used in sparkbun.config.ts files
 */

/**
 * Bun.build() options that can be passed through to the bundler.
 * Excludes options that are controlled by SparkBun (entrypoints, outdir, target).
 * See https://bun.sh/docs/bundler for full documentation.
 */
type BunBuildOptions = Omit<
	Parameters<typeof Bun.build>[0],
	"entrypoints" | "outdir" | "target"
>;

export interface SparkBunConfig {
	/**
	 * Application metadata configuration
	 */
	app: {
		/**
		 * The display name of your application
		 */
		name: string;

		/**
		 * Unique identifier for your application (e.g., "com.example.myapp")
		 * Used for platform-specific identifiers
		 */
		identifier: string;

		/**
		 * Application version string (e.g., "1.0.0")
		 */
		version: string;

		/**
		 * Optional description of the application
		 */
		description?: string;

		/**
		 * Publisher/company name (e.g., "My Company")
		 * Used in Windows file properties and installer metadata
		 */
		publisher?: string;

		/**
		 * Copyright notice (e.g., "Copyright 2026 My Company")
		 * Used in Windows file properties
		 */
		copyright?: string;

		/**
		 * Custom URL schemes to register for deep linking (e.g., ["myapp", "myapp-dev"])
		 * This allows your app to be opened via URLs like myapp://some/path
		 *
		 * Platform support:
		 * - macOS: Fully supported. App must be in /Applications folder for registration to work.
		 * - Windows: Not yet supported
		 * - Linux: Not yet supported
		 *
		 * To handle incoming URLs, listen for the "open-url" event:
		 * ```typescript
		 * SparkBun.events.on("open-url", (e) => {
		 *   console.log("Opened with URL:", e.data.url);
		 * });
		 * ```
		 */
		urlSchemes?: string[];

		/**
		 * File type associations for the application.
		 * Registers document types so the OS can open files with your app
		 * (e.g., double-click in Finder, "Open With" menu, drag-to-dock).
		 *
		 * Platform support:
		 * - macOS: Fully supported. Generates CFBundleDocumentTypes in Info.plist.
		 * - Windows/Linux: Not yet supported.
		 *
		 * Files arrive as file:// URLs via the existing "open-url" event:
		 * ```typescript
		 * SparkBun.events.on("open-url", (e) => {
		 *   if (e.data.url.startsWith("file://")) {
		 *     console.log("Opened file:", e.data.url);
		 *   }
		 * });
		 * ```
		 */
		fileAssociations?: Array<{
			/** File extensions without the leading dot (e.g., ["dotlock", "json"]) */
			ext: string[];
			/** Human-readable name for this file type (e.g., "DotLock Document") */
			name: string;
			/** The app's role for this file type. @default "Viewer" */
			role?: "Editor" | "Viewer" | "Shell" | "None";
			/**
			 * Path to an .icns file for this document type (macOS only).
			 * The file is automatically copied into the app bundle's Resources folder
			 * during the build. Only the filename (without path) is written to Info.plist.
			 */
			icon?: string;
		}>;
	};

	/**
	 * Build configuration options
	 */
	build?: {
		/**
		 * Bun process build configuration.
		 * Accepts all Bun.build() options (plugins, sourcemap, minify, define, etc.)
		 * in addition to the entrypoint. See https://bun.sh/docs/bundler
		 */
		bun?: {
			/**
			 * Entry point for the main Bun process
			 * @default "src/bun/index.ts"
			 */
			entrypoint?: string;
		} & BunBuildOptions;

		/**
		 * Browser view build configurations.
		 * Each view accepts all Bun.build() options (plugins, sourcemap, minify, define, etc.)
		 * in addition to the entrypoint. See https://bun.sh/docs/bundler
		 */
		views?: {
			[viewName: string]: {
				/**
				 * Entry point for this view's TypeScript code
				 */
				entrypoint: string;
			} & BunBuildOptions;
		};

		/**
		 * Files to copy directly to the build output
		 * Key is source path, value is destination path
		 */
		copy?: {
			[sourcePath: string]: string;
		};

		/**
		 * Configuration for the `sparkbun installer` command, which builds a
		 * single-file graphical installer with embedded payload archives.
		 *
		 * Each archive is tarred (preserving its source folder name as the
		 * archive root) and compressed independently. The compiled installer
		 * app reads the embedded `archives.json` manifest and extracts the
		 * payloads itself — the framework does not auto-extract, giving the
		 * installer full control over the process (streaming, progress,
		 * placement, ordering, conditional components, etc.).
		 *
		 * Archives can also be supplied on the CLI via repeated
		 * `--archive name=path` flags; config entries and flags are combined.
		 */
		installer?: {
			archives?: Array<{
				/**
				 * Logical identifier for the archive. Referenced by the app and
				 * used as the manifest key. Must match /^[a-zA-Z_][a-zA-Z0-9_]*$/.
				 */
				name: string;
				/**
				 * Source directory (relative to project root or absolute). The
				 * directory's own name becomes the archive's top-level folder,
				 * so it extracts into the correct subdirectory.
				 *
				 * May also point at a PREBUILT `.tar` / `.tar.gz` / `.tar.zst`
				 * file, which is embedded verbatim (no per-build tar+compress —
				 * useful when a large payload is slow to compress and rarely
				 * changes). Format is taken from the extension; `format`/
				 * `compression` are ignored for prebuilt archives.
				 */
				path: string;
				/**
				 * Compression algorithm.
				 * - "zstd" — best ratio at high levels, streaming decode (default)
				 * - "gzip" — widest compatibility, faster, larger output
				 * @default "zstd"
				 */
				format?: "zstd" | "gzip";
				/**
				 * Compression tier.
				 * - "basic" — Bun's built-in CompressionStream (zstd ≈ level 3,
				 *   gzip ≈ level 6). Fast, streaming, no level control. (default)
				 * - number — explicit level via node:zlib streaming transforms.
				 *   zstd: 1–22 (22 = maximum; large window, smallest output).
				 *   gzip: 1–9. Higher is smaller but slower to compress.
				 * - "none" — no compression; a plain `.tar`. For payloads that
				 *   are already compressed (video, media) where recompression
				 *   wastes build time. The manifest records format "none" and
				 *   the app's extractor must skip its decompression step.
				 * @default "basic"
				 */
				compression?: "none" | "basic" | number;
				/**
				 * Legacy alias for a numeric `compression` tier. Ignored when
				 * `compression` is set.
				 * @deprecated Use `compression` instead.
				 */
				level?: number;
			}>;
		};

		/**
		 * Output folder for built application
		 * @default "build"
		 */
		buildFolder?: string;

		/**
		 * Output folder for distribution artifacts
		 * @default "artifacts"
		 */
		artifactFolder?: string;

		/**
		 * Build targets to compile for
		 * Can be "current", "all", or comma-separated list like "macos-arm64,win-x64"
		 */
		targets?: string;

		/**
		 * Override the CEF (Chromium Embedded Framework) version.
		 * Format: "CEF_VERSION+chromium-CHROMIUM_VERSION"
		 * Example: "144.0.11+ge135be2+chromium-144.0.7559.97"
		 *
		 * Check the sparkbun-cef-compat compatibility matrix for tested combinations
		 * before overriding. Using an untested version may cause runtime issues.
		 * @default Uses the version bundled with this SparkBun release
		 */
		cefVersion?: string;

		/**
		 * Override the Dawn (WebGPU) version.
		 * Format: semver string (e.g., "0.2.3") or tag (e.g., "v0.2.3-beta.0")
		 *
		 * This downloads the specified sparkbun-dawn release and uses it
		 * instead of the latest release.
		 * @default Uses the latest sparkbun-dawn release
		 */
		wgpuVersion?: string;

		/**
		 * Override the Bun runtime version.
		 * Format: semver string (e.g., "1.4.2")
		 *
		 * This downloads the specified Bun version from GitHub releases and uses it
		 * instead of the version bundled with this SparkBun release.
		 * @default Uses the version bundled with this SparkBun release
		 */
		bunVersion?: string;

		/**
		 * Locales to include in the ICU data file (Linux/Windows only).
		 * Set to '*' to include all locales, or specify a subset like ['en', 'de']
		 * to reduce app size. Has no effect on macOS (uses system ICU).
		 * @default '*'
		 */
		locales?: string[] | "*";

		/**
		 * Additional file or directory paths to watch for changes during `sparkbun dev --watch`.
		 * Paths are relative to the project root.
		 * Useful for files that affect your build but aren't listed as entrypoints or copy sources.
		 */
		watch?: string[];

		/**
		 * Glob patterns for files that should not trigger a rebuild when changed.
		 * Patterns are matched against project-relative paths.
		 * The `build/`, `artifacts/`, and `node_modules/` directories are always ignored automatically.
		 */
		watchIgnore?: string[];

		/**
		 * macOS-specific build configuration
		 */
		mac?: {
			/**
			 * Enable code signing for macOS builds
			 * @default false
			 */
			codesign?: boolean;

			/**
			 * Create a DMG artifact for macOS builds.
			 * Disable this for local prototype builds that only need the app bundle and update archive.
			 * @default true
			 */
			createDmg?: boolean;

			/**
			 * Enable notarization for macOS builds (requires codesign)
			 * @default false
			 */
			notarize?: boolean;

			/**
			 * Bundle CEF (Chromium Embedded Framework) instead of using system WebView
			 * @default false
			 */
			bundleCEF?: boolean;

			/**
			 * Bundle Dawn (WebGPU) for GPU-native rendering
			 * @default false
			 */
			bundleWGPU?: boolean;

			/**
			 * Default renderer for webviews when not explicitly specified
			 * @default 'native'
			 */
			defaultRenderer?: "native" | "cef";

			/**
			 * Custom Chromium command-line flags to pass to CEF during initialization.
			 * Keys are flag names without the "--" prefix.
			 * - `true` — add a switch-only flag
			 * - `"value"` — add a flag with a value
			 * - `false` — remove a default flag set by SparkBun
			 *
			 * @example
			 * ```typescript
			 * chromiumFlags: {
			 *   "disable-gpu": false,               // remove SparkBun's default --disable-gpu
			 *   "remote-debugging-port": "9333",    // --remote-debugging-port=9333
			 * }
			 * ```
			 */
			chromiumFlags?: Record<string, string | boolean>;

			/**
			 * macOS entitlements for code signing
			 */
			entitlements?: Record<string, boolean | string | string[]>;

			/**
			 * Path to .iconset folder or .icon file (from Icon Composer)
			 * containing app icons.
			 *
			 * - `.iconset` folders are converted to .icns via iconutil
			 *   (requires Command Line Tools)
			 * - `.icon` files are compiled via actool, producing Assets.car
			 *   for Liquid Glass on macOS 26+ and a .icns fallback for older
			 *   macOS versions (requires Xcode)
			 *
			 * @default "icon.iconset"
			 */
			icons?: string;
		};

		/**
		 * Windows-specific build configuration
		 */
		win?: {
			/**
			 * Bundle CEF (Chromium Embedded Framework) instead of using WebView2
			 * @default false
			 */
			bundleCEF?: boolean;

			/**
			 * Bundle Dawn (WebGPU) for GPU-native rendering
			 * @default false
			 */
			bundleWGPU?: boolean;

			/**
			 * Default renderer for webviews when not explicitly specified
			 * @default 'native'
			 */
			defaultRenderer?: "native" | "cef";

			/**
			 * Custom Chromium command-line flags to pass to CEF during initialization.
			 * Keys are flag names without the "--" prefix.
			 * - `true` — add a switch-only flag
			 * - `"value"` — add a flag with a value
			 * - `false` — remove a default flag set by SparkBun
			 *
			 * @example
			 * ```typescript
			 * chromiumFlags: {
			 *   "disable-gpu": false,               // remove SparkBun's default --disable-gpu
			 *   "remote-debugging-port": "9333",    // --remote-debugging-port=9333
			 * }
			 * ```
			 */
			chromiumFlags?: Record<string, string | boolean>;

			/**
			 * Path to application icon (.ico format)
			 * Used for the installer/extractor wrapper, desktop shortcuts, and taskbar
			 * Should include multiple sizes (16x16, 32x32, 48x48, 256x256) for best results
			 * @example "assets/icon.ico"
			 */
			icon?: string;

			/**
			 * Request administrator privileges on launch.
			 * The app will check for admin at startup and re-launch itself
			 * elevated via UAC if needed.
			 * @default false
			 */
			requireAdmin?: boolean;
		};

		/**
		 * Linux-specific build configuration
		 */
		linux?: {
			/**
			 * Bundle CEF (Chromium Embedded Framework) instead of using GTKWebKit
			 * Recommended on Linux for advanced layer compositing features
			 * @default false
			 */
			bundleCEF?: boolean;

			/**
			 * Bundle Dawn (WebGPU) for GPU-native rendering
			 * @default false
			 */
			bundleWGPU?: boolean;

			/**
			 * Default renderer for webviews when not explicitly specified
			 * @default 'native'
			 */
			defaultRenderer?: "native" | "cef";

			/**
			 * Custom Chromium command-line flags to pass to CEF during initialization.
			 * Keys are flag names without the "--" prefix.
			 * - `true` — add a switch-only flag
			 * - `"value"` — add a flag with a value
			 * - `false` — remove a default flag set by SparkBun
			 *
			 * @example
			 * ```typescript
			 * chromiumFlags: {
			 *   "disable-gpu": false,               // remove SparkBun's default --disable-gpu
			 *   "remote-debugging-port": "9333",    // --remote-debugging-port=9333
			 * }
			 * ```
			 */
			chromiumFlags?: Record<string, string | boolean>;

			/**
			 * Path to application icon (PNG format recommended)
			 * Used for desktop entries, window icons, and taskbar
			 * Should be at least 256x256 pixels for best results
			 * @example "assets/icon.png"
			 */
			icon?: string;

			/**
			 * Request root privileges on launch.
			 * The app will check for root at startup and re-launch itself
			 * via pkexec if needed.
			 * @default false
			 */
			requireAdmin?: boolean;

			/**
			 * Create a .deb package for Debian/Ubuntu.
			 * @default false
			 */
			createDeb?: boolean;

			/**
			 * System library dependencies for the .deb package.
			 * @default ["libwebkit2gtk-4.1-0", "libgtk-3-0t64", "libsoup-3.0-0", "libjavascriptcoregtk-4.1-0", "libayatana-appindicator3-1", "libgdk-pixbuf-2.0-0"]
			 */
			debDependencies?: string[];

			/**
			 * Package maintainer for the .deb control file.
			 * @example "Your Name <you@example.com>"
			 */
			debMaintainer?: string;

			/**
			 * Install prefix for the .deb package.
			 * @default "/opt/<AppNameNoSpaces>"
			 */
			installDir?: string;

			/**
			 * Desktop entry category.
			 * @default "Utility;Application;"
			 */
			category?: string;
		};
	};

	/**
	 * Runtime behaviour configuration.
	 * These values are copied into build.json and available to the Bun process at runtime.
	 * You can add arbitrary keys here and access them via BuildConfig.
	 */
	runtime?: {
		/**
		 * Quit the application when the last BrowserWindow is closed.
		 * @default true
		 */
		exitOnLastWindowClosed?: boolean;

		[key: string]: unknown;
	};

	/**
	 * Build scripts configuration
	 */
	scripts?: {
		/**
		 * Script to run before the build starts
		 * Can be a path to a script file
		 */
		preBuild?: string;

		/**
		 * Script to run after build completes
		 * Can be a path to a script file
		 */
		postBuild?: string;

		/**
		 * Script to run after the app is wrapped (macOS .app bundle created)
		 * Can be a path to a script file
		 */
		postWrap?: string;

		/**
		 * Script to run after packaging is complete
		 * Can be a path to a script file
		 */
		postPackage?: string;
	};

	/**
	 * Release and distribution configuration
	 */
	release?: {
		/**
		 * Base URL for artifact distribution (e.g., S3 bucket, GitHub Releases)
		 * Used for auto-updates and patch generation
		 */
		baseUrl?: string;
		/**
		 * Generate delta patch files by diffing against the previous release.
		 * Disable to skip patch generation for local canary/stable testing.
		 * @default true
		 */
		generatePatch?: boolean;
	};
}
