#!/usr/bin/env python3
import html
import os
import re
from pathlib import Path


SERVICES = (
    "gb32960",
    "jt808",
    "yutong-mqtt",
    "vehicle-history",
    "vehicle-analytics",
)

LOG_DIRS = (
    "lingniu-gb32960-live",
    "lingniu-jt808-live",
    "lingniu-yutong-mqtt-live",
    "lingniu-vehicle-history-live",
    "lingniu-vehicle-analytics-live",
)


def env(name: str, default: str = "") -> str:
    return os.environ.get(name, default)


def xml_value(value: str) -> str:
    return html.escape(value, quote=False)


def replacements() -> dict[str, str]:
    identity_jdbc = env("VEHICLE_IDENTITY_MYSQL_JDBC_URL", "jdbc:mysql://127.0.0.1:3306/vehicle_ingest")
    identity_username = env("VEHICLE_IDENTITY_MYSQL_USERNAME", "")
    identity_password = env("VEHICLE_IDENTITY_MYSQL_PASSWORD", "")
    return {
        "__PROJECT_ROOT__": env("PROJECT_ROOT", str(Path.cwd())),
        "__JAVA_BIN__": env("JAVA_BIN", "/usr/bin/java"),
        "__SHARED_ARCHIVE_PATH__": env("INGEST_ARCHIVE_PATH", str(Path.cwd() / "data/archive-live")),
        "__TDENGINE_JDBC_URL__": env("TDENGINE_JDBC_URL", "jdbc:TAOS-WS://127.0.0.1:6041/vehicle_ts"),
        "__TDENGINE_USERNAME__": env("TDENGINE_USERNAME", "root"),
        "__TDENGINE_PASSWORD__": env("TDENGINE_PASSWORD", ""),
        "__VEHICLE_IDENTITY_MYSQL_JDBC_URL__": identity_jdbc,
        "__VEHICLE_IDENTITY_MYSQL_USERNAME__": identity_username,
        "__VEHICLE_IDENTITY_MYSQL_PASSWORD__": identity_password,
        "__VEHICLE_IDENTITY_MYSQL_REFRESH_INTERVAL__": env("VEHICLE_IDENTITY_MYSQL_REFRESH_INTERVAL", "60s"),
        "__MYSQL_JDBC_URL__": env("MYSQL_JDBC_URL", identity_jdbc),
        "__MYSQL_USERNAME__": env("MYSQL_USERNAME", identity_username),
        "__MYSQL_PASSWORD__": env("MYSQL_PASSWORD", identity_password),
        "__YUTONG_MQTT_ENABLED__": env("YUTONG_MQTT_ENABLED", "false"),
        "__YUTONG_MQTT_URI__": env("YUTONG_MQTT_URI", ""),
        "__YUTONG_MQTT_TOPIC__": env("YUTONG_MQTT_TOPIC", "#"),
        "__YUTONG_MQTT_USERNAME__": env("YUTONG_MQTT_USERNAME", ""),
        "__YUTONG_MQTT_PASSWORD__": env("YUTONG_MQTT_PASSWORD", ""),
        "__YUTONG_MQTT_KEEP_ALIVE_SECONDS__": env("YUTONG_MQTT_KEEP_ALIVE_SECONDS", "20"),
        "__YUTONG_MQTT_CONNECTION_TIMEOUT_SECONDS__": env("YUTONG_MQTT_CONNECTION_TIMEOUT_SECONDS", "10"),
        "__YUTONG_MQTT_TLS_CA_PEM__": env("YUTONG_MQTT_TLS_CA_PEM", ""),
        "__YUTONG_MQTT_TLS_CLIENT_PEM__": env("YUTONG_MQTT_TLS_CLIENT_PEM", ""),
        "__YUTONG_MQTT_TLS_CLIENT_KEY__": env("YUTONG_MQTT_TLS_CLIENT_KEY", ""),
        "__YUTONG_MQTT_TLS_HOSTNAME_VERIFICATION_ENABLED__": env(
            "YUTONG_MQTT_TLS_HOSTNAME_VERIFICATION_ENABLED", "true"),
    }


def render_template(template: str, values: dict[str, str]) -> str:
    rendered = template
    for placeholder, value in values.items():
        rendered = rendered.replace(placeholder, xml_value(value))
    unresolved = sorted(set(re.findall(r"__[A-Z0-9_]+__", rendered)))
    if unresolved:
        raise RuntimeError("unresolved launchctl placeholder(s): " + ", ".join(unresolved))
    return rendered


def main() -> None:
    root = Path(env("PROJECT_ROOT", str(Path.cwd()))).resolve()
    template_dir = Path(__file__).resolve().parent
    launch_agents = Path.home() / "Library/LaunchAgents"
    launch_agents.mkdir(parents=True, exist_ok=True)
    (root / "data").mkdir(parents=True, exist_ok=True)
    for log_dir in LOG_DIRS:
        (Path("/tmp") / log_dir).mkdir(parents=True, exist_ok=True)

    values = replacements()
    for service in SERVICES:
        template_path = template_dir / f"com.lingniu.{service}.plist.template"
        output_path = launch_agents / f"com.lingniu.{service}.plist"
        output_path.write_text(render_template(template_path.read_text(), values), encoding="utf-8")
        print(output_path)


if __name__ == "__main__":
    main()
