"""Windows Service 'ClassroomAgent'.

  python windows_service.py install | start | stop | remove      (jalankan sebagai Administrator)

Service berjalan sebagai LocalSystem karena harus mengubah Windows Firewall, berkas hosts, dan registry kebijakan.
Service TIDAK tersembunyi: tampil di services.msc dengan nama jelas, menulis log ke %ProgramData%\\ClassroomAgent\\agent.log,
dan helper menampilkan banner merah setiap kali layar siswa dipantau.
"""
import asyncio
import logging
import sys
import threading
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent.parent))

import servicemanager  # noqa: E402
import win32event  # noqa: E402
import win32service  # noqa: E402
import win32serviceutil  # noqa: E402

from config import Config  # noqa: E402
from main import setup_logging  # noqa: E402
from services.agent_core import Agent  # noqa: E402


class ClassroomAgentService(win32serviceutil.ServiceFramework):
    _svc_name_ = "ClassroomAgent"
    _svc_display_name_ = "Classroom Management Agent"
    _svc_description_ = "Agen manajemen kelas sekolah: menerima kebijakan internet/browser/aplikasi dari komputer guru. Dipasang oleh administrator sekolah."

    def __init__(self, args):
        super().__init__(args)
        self.stop_evt = win32event.CreateEvent(None, 0, 0, None)
        self.agent: Agent | None = None
        self.loop: asyncio.AbstractEventLoop | None = None

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        if self.agent and self.loop:
            self.loop.call_soon_threadsafe(self.agent._stop.set)
        win32event.SetEvent(self.stop_evt)

    def SvcDoRun(self):
        setup_logging(console=False)
        servicemanager.LogInfoMsg("ClassroomAgent dimulai")
        cfg = Config.load()
        if not cfg.token:
            logging.error("Agent belum terdaftar; service berhenti.")
            return

        def runner():
            self.loop = asyncio.new_event_loop()
            asyncio.set_event_loop(self.loop)
            self.agent = Agent(cfg)
            self.loop.run_until_complete(self.agent.run())
            win32event.SetEvent(self.stop_evt)  # agent selesai (mis. perangkat dilepas) -> service berhenti sendiri

        t = threading.Thread(target=runner, daemon=True)
        t.start()
        win32event.WaitForSingleObject(self.stop_evt, win32event.INFINITE)
        t.join(timeout=10)


if __name__ == "__main__":
    if len(sys.argv) == 1:
        servicemanager.Initialize()
        servicemanager.PrepareToHostSingle(ClassroomAgentService)
        servicemanager.StartServiceCtrlDispatcher()
    else:
        win32serviceutil.HandleCommandLine(ClassroomAgentService)
