from __future__ import annotations
from PyQt6.QtCore import QObject, QProcess, pyqtSignal
from pathlib import Path

class HugoWorker(QObject):
    log_line = pyqtSignal(str)
    started = pyqtSignal()
    stopped = pyqtSignal()
    error = pyqtSignal(str)

    def __init__(self, repo_path: Path, parent=None):
        super().__init__(parent)
        self._repo_path = repo_path
        self._process = QProcess(self)
        self._process.readyReadStandardOutput.connect(self._on_stdout)
        self._process.readyReadStandardError.connect(self._on_stderr)
        self._process.finished.connect(self._on_finished)
        self._process.started.connect(self.started)

    @property
    def is_running(self) -> bool:
        return self._process.state() == QProcess.ProcessState.Running

    def start(self):
        if self.is_running:
            return
        self._process.setWorkingDirectory(str(self._repo_path))
        self._process.start("hugo", ["server", "-D"])

    def stop(self):
        if self.is_running:
            self._process.terminate()
            self._process.waitForFinished(3000)
            # stopped emitted by _on_finished; don't double-emit

    def _on_stdout(self):
        data = self._process.readAllStandardOutput().data().decode("utf-8", errors="replace")
        for line in data.splitlines():
            self.log_line.emit(line)

    def _on_stderr(self):
        data = self._process.readAllStandardError().data().decode("utf-8", errors="replace")
        for line in data.splitlines():
            self.log_line.emit(line)

    def _on_finished(self, exit_code: int, _):
        if exit_code != 0:
            self.error.emit(f"hugo server exited with code {exit_code}")
        self.stopped.emit()
