import subprocess
from pathlib import Path

from vagary.providers.base import BaseProvider


class VagrantProvider(BaseProvider):
    def __init__(self, box: str, memory: int, cpus: int, vnc_port: int = 5900):
        self.box = box
        self.memory = memory
        self.cpus = cpus
        self.vnc_host = "127.0.0.1"
        self.vnc_port = vnc_port

        self.work_dir = Path("./tmp")
        self.work_dir.mkdir(exist_ok=True)
        self.vagrantfile_path = self.work_dir / "Vagrantfile"

    def start(self) -> None:
        self._create_vagrantfile()
        subprocess.run(
            ["vagrant", "destroy", "--force"],
            cwd=self.work_dir,
            check=True,
        )
        print(">> Running vagrant up...")
        subprocess.run(
            ["vagrant", "up"],
            cwd=self.work_dir,
            check=True,
        )
        print("> Vagrant is up")

    def stop(self) -> None:
        subprocess.run(
            ["vagrant", "destroy", "--force"],
            cwd=self.work_dir,
            check=True,
        )

    def get_ssh_config(self) -> dict:
        result = subprocess.run(
            ["vagrant", "ssh-config"],
            cwd=self.work_dir,
            capture_output=True,
            text=True,
            check=True,
        )
        config = {}
        for line in result.stdout.splitlines():
            if line.strip():
                key, value = line.strip().split(None, 1)
                config[key] = value
        return config

    def _create_vagrantfile(self) -> None:
        content = f'''# -*- mode: ruby -*-
Vagrant.configure("2") do |config|
  config.vm.box = "{self.box}"

  config.vm.provider "libvirt" do |libvirt|
    libvirt.memory = {self.memory}
    libvirt.cpus = {self.cpus}

    libvirt.graphics_type = "vnc"
    libvirt.graphics_port = {self.vnc_port}
    libvirt.graphics_ip = "127.0.0.1"
    libvirt.video_type = "qxl"
    libvirt.video_accel3d = false
  end
end
'''
        self.vagrantfile_path.write_text(content)
        print(f"> Vagrantfile created: {self.vagrantfile_path}")
