package main

import (
	"fmt"
	"os"
	"os/exec"
	"strings"
)

// MiasmaInstaller represents the installer for Miasma OS
type MiasmaInstaller struct {
	device             string
	username           string
	password           string
	installHardened    bool
	installPackages    []string
}

// NewMiasmaInstaller creates a new MiasmaInstaller instance
func NewMiasmaInstaller() *MiasmaInstaller {
	return &MiasmaInstaller{
		installHardened: true,
		installPackages: []string{},
	}
}

func main() {
	installer := NewMiasmaInstaller()
	
	// Get system information
	fmt.Println("Miasma OS Installer")
	fmt.Println("===================")
	
	// Create temporary config file
	if err := installer.createTempConfig(); err != nil {
		fmt.Printf("Error creating config: %v\n", err)
		os.Exit(1)
	}
	
	// Make sure we have root privileges
	if err := checkRootPrivileges(); err != nil {
		fmt.Printf("Error: %v\n", err)
		os.Exit(1)
	}
	
	// Get user input
	if err := installer.getUserInput(); err != nil {
		fmt.Printf("Error getting user input: %v\n", err)
		os.Exit(1)
	}
	
	// Validate disk selection
	if err := installer.validateDisk(); err != nil {
		fmt.Printf("Error validating disk: %v\n", err)
		os.Exit(1)
	}
	
	// Run the actual installation
	if err := installer.runInstallation(); err != nil {
		fmt.Printf("Installation failed: %v\n", err)
		os.Exit(1)
	}
	
	fmt.Println("Installation completed successfully!")
}

// detectDisks returns a list of available disks
func detectDisks() ([]string, error) {
	cmd := exec.Command("lsblk", "-o", "NAME,SIZE,TYPE,MOUNTPOINT", "-n", "-l")
	output, err := cmd.Output()
	if err != nil {
		return nil, err
	}
	
	lines := strings.Split(strings.TrimSpace(string(output)), "\n")
	var disks []string
	
	for _, line := range lines {
		fields := strings.Fields(line)
		if len(fields) >= 3 {
			name := fields[0]
			deviceType := fields[2]
			
			// Only include whole disks (not partitions)
			if deviceType == "disk" {
				disks = append(disks, "/dev/"+name)
			}
		}
	}
	
	return disks, nil
}

// checkRootPrivileges checks if the installer is running with root privileges
func checkRootPrivileges() error {
	cmd := exec.Command("id", "-u")
	output, err := cmd.Output()
	if err != nil {
		return fmt.Errorf("failed to check privileges: %v", err)
	}
	
	outputStr := strings.TrimSpace(string(output))
	if outputStr != "0" {
		return fmt.Errorf("this installer must be run as root")
	}
	
	return nil
}

// getUserInput prompts user for installation parameters
func (m *MiasmaInstaller) getUserInput() error {
	// Get disk selection
	diskList, err := detectDisks()
	if err != nil {
		return fmt.Errorf("failed to detect disks: %v", err)
	}
	
	if len(diskList) == 0 {
		return fmt.Errorf("no disks detected")
	}
	
	fmt.Println("Available disks:")
	for i, disk := range diskList {
		fmt.Printf("%d. %s\n", i+1, disk)
	}
	
	fmt.Printf("Select disk (1-%d): ", len(diskList))
	var diskChoice int
	_, err = fmt.Scanf("%d", &diskChoice)
	if err != nil || diskChoice < 1 || diskChoice > len(diskList) {
		return fmt.Errorf("invalid disk selection")
	}
	
	m.device = diskList[diskChoice-1]
	
	// Get username and password
	fmt.Print("Enter username: ")
	_, err = fmt.Scanf("%s", &m.username)
	if err != nil {
		return fmt.Errorf("failed to read username: %v", err)
	}
	
	fmt.Print("Enter password: ")
	_, err = fmt.Scanf("%s", &m.password)
	if err != nil {
		return fmt.Errorf("failed to read password: %v", err)
	}
	
	fmt.Printf("Installing to %s with user %s\n", m.device, m.username)
	return nil
}

// validateDisk validates the selected disk
func (m *MiasmaInstaller) validateDisk() error {
	if m.device == "" {
		return fmt.Errorf("no device selected")
	}
	
	// Simple check: device should start with /dev/
	if !strings.HasPrefix(m.device, "/dev/") {
		return fmt.Errorf("invalid device path: %s", m.device)
	}
	
	return nil
}

// createTempConfig creates a temporary alis configuration for Miasma OS
func (m *MiasmaInstaller) createTempConfig() error {
	config := fmt.Sprintf(`# Miasma OS Installer Configuration
# Based on alis configuration format

# init
LOG_TRACE="true"
LOG_FILE="false"

# partition
DEVICE="%s"
DEVICE_TRIM="true"
LVM="false"
LUKS_PASSWORD=""
LUKS_PASSWORD_RETYPE=""
FILE_SYSTEM_TYPE="btrfs"
BTRFS_SUBVOLUMES_MOUNTPOINTS=("root,root,/" "home,home,/home" "var,var,/var" "snapshots,snapshots,/.snapshots")
SWAP_SIZE="4096"
PARTITION_MODE="auto"
PARTITION_MOUNT_POINTS=("1=/boot" "2=/")
GPT_AUTOMOUNT="false"

# install
REFLECTOR="true"
REFLECTOR_COUNTRIES=("United States")
PACMAN_MIRROR=""
PACMAN_PARALLEL_DOWNLOADS="true"
KERNELS="linux-hardened"
KERNELS_COMPRESSION="zstd"
KERNELS_PARAMETERS=""

# aur
AUR_PACKAGE="paru-bin"

# display driver
DISPLAY_DRIVER="auto"
KMS="true"
FASTBOOT="true"
FRAMEBUFFER_COMPRESSION="true"
DISPLAY_DRIVER_DDX="false"
VULKAN="true"
DISPLAY_DRIVER_HARDWARE_VIDEO_ACCELERATION="true"
DISPLAY_DRIVER_HARDWARE_VIDEO_ACCELERATION_INTEL="intel-media-driver"

# config
TIMEZONE="UTC"
LOCALES=("en_US.UTF-8 UTF-8")
LOCALE_CONF=("LANG=en_US.UTF-8")
KEYLAYOUT="us"
KEYMODEL=""
KEYVARIANT=""
KEYOPTIONS=""
KEYMAP="us"
FONT=""
FONT_MAP=""
HOSTNAME="miasma"
ROOT_PASSWORD="%s"
ROOT_PASSWORD_RETYPE="%s"

# user
USER_NAME="%s"
USER_PASSWORD="%s"
USER_PASSWORD_RETYPE="%s"
ADDITIONAL_USERS=()

# systemd-homed
SYSTEMD_HOMED="false"
SYSTEMD_HOMED_STORAGE="directory"
SYSTEMD_HOMED_STORAGE_LUKS_TYPE="ext4"

# mkinitcpio
HOOKS="base udev autodetect microcode modconf kms keyboard keymap consolefont block btrfs filesystems fsck"
MODULES=""
UKI="false"
PLYMOUTH="false"

# bootloader
BOOTLOADER="systemd"
SECURE_BOOT="false"

# shell
CUSTOM_SHELL="zsh"

# desktop
DESKTOP_ENVIRONMENT="cosmic"
DISPLAY_MANAGER="auto"

# packages
PACKAGES_MULTILIB="false"
PACKAGES_INSTALL="true"
PACKAGES_PIPEWIRE="true"

# provision
PROVISION="false"

# misc
FWUPD="false"
VAGRANT="false"

# systemd
SYSTEMD_UNITS="+systemd-timesyncd.service +apparmor.service"

# reboot
REBOOT="false"
`,
		m.device, m.password, m.password, m.username, m.password, m.password)
	
	return os.WriteFile("alis.conf", []byte(config), 0644)
}

// runInstallation executes the installation process
func (m *MiasmaInstaller) runInstallation() error {
	// Create a temporary file to store the username for post-install script
	err := os.WriteFile("/tmp/miasma-username", []byte(m.username), 0644)
	if err != nil {
		return fmt.Errorf("failed to create username file: %v", err)
	}
	
	// Copy our custom packages configuration to the alis directory
	cmd := exec.Command("cp", "alis-packages.conf", "alis/alis-packages.conf")
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("failed to copy packages config: %v", err)
	}
	
	// Copy post-install script to the chroot environment
	cmd = exec.Command("cp", "miasma-post-install.sh", "/mnt/miasma-post-install.sh")
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("failed to copy post-install script: %v", err)
	}
	
	// Prepare the alis script command
	cmd = exec.Command("./alis.sh")
	cmd.Dir = "./alis"
	
	// Set environment variables
	cmd.Env = append(os.Environ(), 
		"WARNING_CONFIRM=false",
		"ALIS_CONF_FILE=../alis.conf",
	)
	
	// Start the installation
	fmt.Println("Starting Arch Linux installation with alis...")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("installation failed: %v\nOutput: %s", err, string(output))
	}
	
	fmt.Printf("Installation completed. Applying Miasma OS configurations...\n")
	
	// Run post-installation script
	fmt.Println("Running post-installation setup...")
	cmd = exec.Command("bash", "/mnt/miasma-post-install.sh")
	output, err = cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("post-installation failed: %v\nOutput: %s", err, string(output))
	}
	
	fmt.Printf("Post-installation output: %s\n", output)
	
	return nil
}

