// Package config handles QVM configuration loading and management.
package config

import (
	"os"
	"path/filepath"
)

// XDG-compliant directory paths matching bash lib/common.sh exactly

var (
	// DataDir is the base directory for QVM data files (base image, runner)
	// Defaults to $HOME/.local/share/qvm
	DataDir = getXDGPath("XDG_DATA_HOME", ".local/share", "qvm")

	// StateDir is the directory for QVM runtime state (overlay, PID, port files)
	// Defaults to $HOME/.local/state/qvm
	StateDir = getXDGPath("XDG_STATE_HOME", ".local/state", "qvm")

	// CacheDir is the directory for shared build caches (cargo, pnpm, sccache)
	// Defaults to $HOME/.cache/qvm
	CacheDir = getXDGPath("XDG_CACHE_HOME", ".cache", "qvm")

	// ConfigDir is the directory for QVM configuration (flake, qvm.toml)
	// Defaults to $HOME/.config/qvm
	ConfigDir = getXDGPath("XDG_CONFIG_HOME", ".config", "qvm")
)

// Path constants for VM artifacts
var (
	// BaseImage is the path to the base VM image (read-only)
	BaseImage = filepath.Join(DataDir, "base.qcow2")

	// VMRunner is the path to the VM runner script
	VMRunner = filepath.Join(DataDir, "run-vm")

	// Overlay is the path to the VM overlay image (copy-on-write)
	Overlay = filepath.Join(StateDir, "qvm-dev.qcow2")

	// PIDFile is the path to the VM process ID file
	PIDFile = filepath.Join(StateDir, "vm.pid")

	// SSHPortFile is the path to the SSH port file
	SSHPortFile = filepath.Join(StateDir, "ssh.port")

	// SerialLog is the path to the VM serial console log
	SerialLog = filepath.Join(StateDir, "serial.log")

	// WorkspacesFile is the path to the workspaces registry JSON
	WorkspacesFile = filepath.Join(StateDir, "workspaces.json")

	// QMPSocket is the path to the QMP (QEMU Machine Protocol) socket
	QMPSocket = filepath.Join(StateDir, "qmp.sock")

	// UserFlake is the path to the user's customizable NixOS flake
	UserFlake = filepath.Join(ConfigDir, "flake")

	// ConfigFile is the path to the QVM TOML configuration file
	ConfigFile = filepath.Join(ConfigDir, "qvm.toml")
)

// Cache directories for 9p mounts (shared between host and VM)
var (
	// CargoHome is the shared Cargo registry/cache directory
	CargoHome = filepath.Join(CacheDir, "cargo-home")

	// CargoTarget is the shared Cargo build artifacts directory
	CargoTarget = filepath.Join(CacheDir, "cargo-target")

	// PnpmStore is the shared pnpm content-addressable store
	PnpmStore = filepath.Join(CacheDir, "pnpm-store")

	// Sccache is the shared sccache compilation cache
	Sccache = filepath.Join(CacheDir, "sccache")
)

// Host config directories to mount in VM (read-write for tools that need it)
var (
	// HostOpencodeConfig is the path to the host's opencode configuration
	// Defaults to $HOME/.config/opencode
	HostOpencodeConfig = getXDGPath("XDG_CONFIG_HOME", ".config", "opencode")
)

// getXDGPath returns an XDG-compliant path with fallback.
// Args:
//   - xdgEnv: XDG environment variable to check (e.g., "XDG_DATA_HOME")
//   - fallbackPath: relative path from $HOME if xdgEnv is not set (e.g., ".local/share")
//   - suffix: additional path suffix to append (e.g., "qvm")
//
// Returns the resolved absolute path.
func getXDGPath(xdgEnv, fallbackPath, suffix string) string {
	base := os.Getenv(xdgEnv)
	if base == "" {
		home := os.Getenv("HOME")
		if home == "" {
			// Fallback to current directory if HOME is not set
			home = "."
		}
		base = filepath.Join(home, fallbackPath)
	}
	return filepath.Join(base, suffix)
}

// EnsureDirs creates all required QVM directories if they don't exist.
// Returns error if directory creation fails.
func EnsureDirs() error {
	dirs := []string{
		DataDir,
		StateDir,
		CacheDir,
		ConfigDir,
		CargoHome,
		CargoTarget,
		PnpmStore,
		Sccache,
	}

	for _, dir := range dirs {
		if err := os.MkdirAll(dir, 0755); err != nil {
			return err
		}
	}

	return nil
}
