# retoor <retoor@molodetz.nl>

from __future__ import annotations

import re

from faker import Faker

from devplacepy.config import WORKSPACE_TUNNEL_DOMAIN
from devplacepy.database import get_setting, get_table

LABEL = re.compile(r"^[a-z0-9]([a-z0-9-]{0,48}[a-z0-9])?$")
MAX_ATTEMPTS = 12

_faker = Faker()


def domain() -> str:
    return get_setting("workspace_tunnel_domain", WORKSPACE_TUNNEL_DOMAIN).strip(".")


def host_pattern() -> str:
    return get_setting("workspace_hostname_pattern", "{name}.{domain}")


def port_pattern() -> str:
    return get_setting("workspace_port_hostname_pattern", "{port}-{name}.{domain}")


def is_valid_label(value: str) -> bool:
    return bool(value) and bool(LABEL.match(value))


def _slugify(value: str) -> str:
    cleaned = re.sub(r"[^a-z0-9]+", "-", value.lower()).strip("-")
    return cleaned[:49].strip("-")


def candidate(index: int) -> str:
    words = [_slugify(_faker.word()) for _ in range(2)]
    words = [word for word in words if word]
    if not words:
        words = ["workspace"]
    name = "-".join(words)
    if index:
        name = f"{name}-{index}"
    return name if is_valid_label(name) else "workspace"


def taken(name: str) -> bool:
    return bool(get_table("instances").find_one(tunnel_name=name, deleted_at=None))


def generate(fallback_uid: str = "") -> str:
    for attempt in range(MAX_ATTEMPTS):
        name = candidate(attempt)
        if not taken(name):
            return name
    tail = (fallback_uid or "").replace("-", "")[-8:]
    return f"workspace-{tail}" if tail else "workspace"


def hostname_for(name: str, port: int = 0) -> str:
    if not name:
        return ""
    pattern = port_pattern() if port else host_pattern()
    return pattern.format(name=name, domain=domain(), port=port)


def proxy_uri_template(name: str) -> str:
    if not name:
        return ""
    return "https://" + port_pattern().format(
        name=name, domain=domain(), port="{{port}}"
    )


def is_tunnel_host(host: str) -> bool:
    if not host:
        return False
    bare = host.split(":", 1)[0].lower().rstrip(".")
    suffix = "." + domain().lower()
    return bare.endswith(suffix)
