from pathlib import Path

import jinja2

from nebula_cert_manager.models import ClientInfo, LighthouseConfig


TEMPLATE_DIR = Path(__file__).parent / "templates"

DEFAULT_OUTBOUND_RULES: list[dict] = [
    {"port": "any", "proto": "any", "host": "any"},
]
DEFAULT_INBOUND_RULES: list[dict] = [
    {"port": "any", "proto": "icmp", "host": "any"},
]


def render_client_config(
    ca_cert: str,
    client: ClientInfo,
    lighthouses: list[LighthouseConfig],
    template_path: Path | None = None,
    inbound_rules: list[dict] | None = None,
    outbound_rules: list[dict] | None = None,
    am_lighthouse: bool = False,
    tun_dev: str = "nebula1",
    blocklist: list[str] | None = None,
    listen_port: int | None = None,
    am_relay: bool = False,
    relays: list[str] | None = None,
) -> str:
    loaders: list[jinja2.BaseLoader] = []
    if template_path:
        loaders.append(jinja2.FileSystemLoader(template_path.parent))
    loaders.append(jinja2.FileSystemLoader(TEMPLATE_DIR))

    env = jinja2.Environment(
        loader=jinja2.ChoiceLoader(loaders),
        undefined=jinja2.StrictUndefined,
        keep_trailing_newline=True,
        trim_blocks=True,
        lstrip_blocks=True,
    )

    if template_path:
        template = env.get_template(template_path.name)
    else:
        template = env.get_template("client_config.yml.j2")

    return template.render(
        ca_cert=ca_cert,
        client_cert=client.cert,
        client_key=client.key,
        lighthouses=lighthouses,
        am_lighthouse=am_lighthouse,
        tun_dev=tun_dev,
        inbound_rules=inbound_rules
        if inbound_rules is not None
        else DEFAULT_INBOUND_RULES,
        outbound_rules=outbound_rules
        if outbound_rules is not None
        else DEFAULT_OUTBOUND_RULES,
        blocklist=blocklist or [],
        listen_port=listen_port,
        am_relay=am_relay,
        relays=relays or [],
    )
