import html

_SELF_CLOSING = {"br", "img", "hr", "meta", "link", "input"}


def _normalize_attr_name(name):
    if name.endswith("_"):
        name = name[:-1]
    if name.startswith("_"):
        name = name[1:]
    return name


def _format_attrs(attrs):
    if not attrs:
        return ""
    parts = []
    for key, value in attrs.items():
        if value is None:
            continue
        key = _normalize_attr_name(key)
        value = html.escape(str(value), quote=True)
        parts.append(f' {key}="{value}"')
    return "".join(parts)


class _Tag:
    def __init__(self, page, name):
        self._page = page
        self._name = name

    def __call__(self, *content, **attrs):
        attr_text = _format_attrs(attrs)
        if self._name in _SELF_CLOSING:
            self._page._append(f"<{self._name}{attr_text} />")
            return None
        if content:
            inner = "".join(str(part) for part in content)
            self._page._append(f"<{self._name}{attr_text}>{inner}</{self._name}>")
            return None
        self._page._append(f"<{self._name}{attr_text}>")
        return None

    def close(self):
        if self._name in _SELF_CLOSING:
            return None
        self._page._append(f"</{self._name}>")
        return None


class HtmlPage:
    def __init__(self, mode=None):
        self._parts = []
        self._title = ""
        self._footer = ""
        self._mode = mode
        self._init_called = False

    def _append(self, text):
        self._parts.append(text)

    def init(self, title="", footer=""):
        self._title = title
        self._footer = footer
        self._init_called = True

    def escape(self, text):
        return html.escape(str(text), quote=True)

    def __getattr__(self, name):
        if name.startswith("_"):
            raise AttributeError(name)
        tag = _Tag(self, name)
        self.__dict__[name] = tag
        return tag

    def __str__(self):
        title = html.escape(self._title, quote=True) if self._title else ""
        footer = html.escape(self._footer, quote=True) if self._footer else ""
        parts = [
            "<!DOCTYPE html>",
            "<html>",
            "<head>",
            '<meta charset="utf-8" />',
        ]
        if title:
            parts.append(f"<title>{title}</title>")
        parts.extend(["</head>", "<body>"])
        parts.extend(self._parts)
        if footer:
            parts.append(f'<div class="footer">{footer}</div>')
        parts.extend(["</body>", "</html>"])
        return "\n".join(parts)
