# Credit: Dai Chao Online == Date: 2026-02-23
import os
import subprocess
import time

import emulator


class EmulatorManager:
    def __init__(self, ld_dir):
        self.ld_instance = emulator.LDPlayer(ld_dir)
        self.ldplayer = self.ld_instance.emulators
        self.creation_flags = subprocess.CREATE_NO_WINDOW if os.name == "nt" else 0

    def launch_instance(self, index):
        self.ldplayer[index].start()

    def stop_instance(self, index):
        self.ldplayer[index].quit()

    def reboot_instance(self, index, delay=3):
        self.stop_instance(index)
        time.sleep(delay)
        self.launch_instance(index)

    def organize_windows(self):
        self.ld_instance.sort_window()

    def check_status(self, index):
        return "Running" if self.ldplayer[index].is_running() else "Stopped"

    def get_instance_name(self, index):
        return self.ldplayer[index].name

    def calculate_vms_size(self, index, ld_dir):
        vms_folder = os.path.join(ld_dir, "vms", f"leidian{index}")
        if not os.path.exists(vms_folder):
            return False

        total_bytes = 0
        for dirpath, _, filenames in os.walk(vms_folder):
            for f in filenames:
                fp = os.path.join(dirpath, f)
                total_bytes += os.path.getsize(fp)

        size_mb = total_bytes / (1024 * 1024)
        size_gb = total_bytes / (1024 * 1024 * 1024)

        if size_gb >= 1:
            return f"{size_gb:.1f} GB"
        else:
            return f"{size_mb:.1f} MB"

    def change_emulator_settings(
        self, index, resolution=None, cpu=None, memory=None, dpi=None
    ):
        emulator_instance = self.ldplayer[index]
        cmd = [
            os.path.join(self.ld_instance.ld_dir, "ldconsole.exe"),
            "modify",
            "--name",
            emulator_instance.name,
        ]

        if resolution:
            if isinstance(resolution, tuple):
                if len(resolution) == 2:
                    if dpi is None:
                        raise ValueError(
                            "DPI must be provided when resolution is a tuple of (width, height)"
                        )
                    res_str = f"{resolution[0]},{resolution[1]},{dpi}"
                elif len(resolution) == 3:
                    res_str = f"{resolution[0]},{resolution[1]},{resolution[2]}"
                else:
                    raise ValueError(
                        "Resolution tuple must be (width, height) or (width, height, dpi)"
                    )
            elif isinstance(resolution, str):
                if "x" in resolution:
                    width, height = resolution.lower().split("x")
                    if dpi is None:
                        raise ValueError(
                            "DPI must be provided when resolution is a string"
                        )
                    res_str = f"{width},{height},{dpi}"
                else:
                    raise ValueError(
                        "Resolution string must be in 'widthxheight' format"
                    )
            else:
                raise ValueError("Resolution must be tuple or string")

            cmd.extend(["--resolution", res_str])

        if cpu:
            cmd.extend(["--cpu", str(cpu)])
        if memory:
            cmd.extend(["--memory", str(memory)])

        result = subprocess.run(
            cmd, capture_output=True, text=True, creationflags=self.creation_flags
        )
        if result.returncode != 0:
            raise RuntimeError(f"Failed to change settings: {result.stderr.strip()}")

        self.ldplayer = self.ld_instance.emulators
        return True

    def reset_emulator_settings(self, index):
        emulator_instance = self.ldplayer[index]
        cmd = [
            os.path.join(self.ld_instance.ld_dir, "ldconsole.exe"),
            "modify",
            "--name",
            emulator_instance.name,
            "--resolution",
            "720, 1280, 320",
            "--cpu",
            "2",
            "--memory",
            "2048",
        ]

        result = subprocess.run(
            cmd, capture_output=True, text=True, creationflags=self.creation_flags
        )

        if result.returncode != 0:
            raise RuntimeError(f"Failed to reset settings: {result.stderr.strip()}")

        self.ldplayer = self.ld_instance.emulators
        return True
