#!/usr/bin/env python3
import os
import signal
import subprocess
import sys
import time
from pathlib import Path


ROOT = Path(__file__).resolve().parent
ENV_FILE = ROOT / ".env"


def load_env_file() -> None:
    if not ENV_FILE.exists():
      return

    for raw_line in ENV_FILE.read_text().splitlines():
        line = raw_line.strip()
        if not line or line.startswith("#") or "=" not in line:
            continue

        key, value = line.split("=", 1)
        os.environ.setdefault(key.strip(), value.strip())


def start_process(command: list[str]) -> subprocess.Popen[str]:
    return subprocess.Popen(
        command,
        cwd=ROOT,
        env=os.environ.copy(),
        text=True,
    )


def main() -> int:
    load_env_file()

    web_port = os.environ.get("WEB_PORT", "3000")

    processes = [
        start_process(["npm", "start", "--workspace", "@tracker/api"]),
        start_process(
            [
                "npm",
                "start",
                "--workspace",
                "@tracker/web",
                "--",
                "--hostname",
                "0.0.0.0",
                "--port",
                web_port,
            ],
        ),
    ]

    def shutdown(*_args: object) -> None:
        for process in processes:
            if process.poll() is None:
                process.terminate()

        deadline = time.time() + 10
        for process in processes:
            if process.poll() is None:
                timeout = max(0, deadline - time.time())
                try:
                    process.wait(timeout=timeout)
                except subprocess.TimeoutExpired:
                    process.kill()

        sys.exit(0)

    signal.signal(signal.SIGTERM, shutdown)
    signal.signal(signal.SIGINT, shutdown)

    while True:
        for process in processes:
            code = process.poll()
            if code is not None:
                shutdown()
                return code
        time.sleep(1)


if __name__ == "__main__":
    sys.exit(main())
