#!/usr/bin/env python3
"""Render cloud configuration SQL without printing secret values."""

import argparse
import os
import re
from pathlib import Path


KEY_RE = re.compile(r"^[A-Z][A-Z0-9_]*$")


def load_env(path: Path) -> dict[str, str]:
    values: dict[str, str] = {}
    for raw in path.read_text(encoding="utf-8").splitlines():
        line = raw.rstrip("\r")
        if not line or line.startswith("#"):
            continue
        if "=" not in line:
            raise ValueError(f"invalid env line in {path}")
        key, value = line.split("=", 1)
        if not KEY_RE.fullmatch(key):
            raise ValueError(f"invalid env key: {key}")
        values[key] = value
    return values


def required(values: dict[str, str], key: str) -> str:
    value = values.get(key, "")
    if not value or value.startswith(("REQUIRED", "CHANGE_ME", "TODO")):
        raise ValueError(f"missing required value: {key}")
    return value


def sql_hex(value: str) -> str:
    return "CONVERT(0x" + value.encode("utf-8").hex() + " USING utf8mb4)"


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--project-env", type=Path, required=True)
    parser.add_argument("--secrets-env", type=Path, required=True)
    parser.add_argument("--output", type=Path, required=True)
    args = parser.parse_args()

    values = load_env(args.project_env)
    values.update(load_env(args.secrets_env))
    restaurant_id = required(values, "CONFIG_RESTAURANT_ID")
    if not restaurant_id.isdigit():
        raise ValueError("CONFIG_RESTAURANT_ID must be numeric")

    mqtt_auth_mode = required(values, "ALIYUN_MQTT_AUTH_MODE")
    instance_generation = required(values, "ALIYUN_MQTT_INSTANCE_GENERATION")
    if mqtt_auth_mode not in {"signature", "device-credential"}:
        raise ValueError("ALIYUN_MQTT_AUTH_MODE must be signature or device-credential")
    if instance_generation not in {"new", "existing-signature-enabled"}:
        raise ValueError(
            "ALIYUN_MQTT_INSTANCE_GENERATION must be new or existing-signature-enabled"
        )
    if mqtt_auth_mode == "signature" and instance_generation != "existing-signature-enabled":
        raise ValueError("signature auth is allowed only for an existing signature-enabled instance")
    if mqtt_auth_mode == "device-credential" and instance_generation != "new":
        raise ValueError("device-credential must use ALIYUN_MQTT_INSTANCE_GENERATION=new")

    mappings = {
        "ali_mqtt_disjunctor": "1",
        "ali_mqtt_auth_mode": mqtt_auth_mode,
        "ali_mqtt_accessKey": required(values, "ALIYUN_MQTT_CREDENTIAL_ID"),
        "ali_mqtt_secretKey": required(values, "ALIYUN_MQTT_CREDENTIAL_SECRET"),
        "ali_mqtt_endPoint": required(values, "ALIYUN_MQTT_ENDPOINT"),
        "ali_mqtt_instanceId": required(values, "ALIYUN_MQTT_INSTANCE_ID"),
        "ali_mqtt_topic": required(values, "ALIYUN_MQTT_TOPIC"),
        "ali_mqtt_groupId": required(values, "ALIYUN_MQTT_GROUP_ID"),
        "ali_mqtt_deviceId": required(values, "ALIYUN_MQTT_PUBLISH_DEVICE_ID"),
        "ali_mqtt_listener_deviceId": required(values, "ALIYUN_MQTT_LISTENER_DEVICE_ID"),
        "ali_mqtt_shared_subscribe": required(values, "ALIYUN_MQTT_SHARED_SUBSCRIBE"),
        "ossDisjunctor": "1",
        "ossAccessKeyId": required(values, "ALIYUN_OSS_ACCESS_KEY_ID"),
        "ossAccessKeySecret": required(values, "ALIYUN_OSS_ACCESS_KEY_SECRET"),
        "ossEndpoint": required(values, "ALIYUN_OSS_ENDPOINT"),
        "ossBucket": required(values, "ALIYUN_OSS_BUCKET"),
        "ossHost": required(values, "ALIYUN_OSS_PUBLIC_HOST"),
        "businessIdentify": required(values, "BUSINESS_ID"),
    }

    statements = [
        "SET sql_safe_updates = 1;",
        "START TRANSACTION;",
        "INSERT INTO `ydy_config` "
        "(`config_key`, `config_value`, `config_desc`, `status`, `restaurant_id`, "
        "`is_show`, `create_time`, `update_time`) "
        f"SELECT {sql_hex('ali_mqtt_auth_mode')}, {sql_hex(mqtt_auth_mode)}, "
        f"{sql_hex('Alibaba Cloud MQTT authentication mode')}, 1, {restaurant_id}, "
        "0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP "
        "WHERE NOT EXISTS (SELECT 1 FROM `ydy_config` "
        f"WHERE `config_key` = {sql_hex('ali_mqtt_auth_mode')} "
        f"AND `restaurant_id` = {restaurant_id} AND `status` = 1);",
    ]
    for key, value in mappings.items():
        statements.append(
            "UPDATE `ydy_config` SET `config_value` = "
            f"{sql_hex(value)} WHERE `config_key` = {sql_hex(key)} "
            f"AND `restaurant_id` = {restaurant_id} AND `status` = 1;"
        )
    safe_keys = ",".join(sql_hex(key) for key in mappings)
    statements.extend(
        [
            "COMMIT;",
            "SELECT `config_key`, LENGTH(`config_value`) AS value_length "
            f"FROM `ydy_config` WHERE `config_key` IN ({safe_keys}) "
            f"AND `restaurant_id` = {restaurant_id} AND `status` = 1 "
            "ORDER BY `config_key`;",
        ]
    )
    args.output.write_text("\n".join(statements) + "\n", encoding="utf-8")
    os.chmod(args.output, 0o600)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
