#!/usr/bin/env python3
"""
e5_format_html.py — Форматирователь HTML: разбивает на строки по тегам,
БЕЗ добавления отступов. Просто каждый тег на новой строке.

Использование:
    python e5_format_html.py input.html              → выводит в stdout
    python e5_format_html.py input.html output.html  → сохраняет в файл
    python e5_format_html.py --dir ./folder           → все .html в папке (на месте)
"""

import os
import re
import sys

# Теги, после открывающего/закрывающего которых ставим перенос
BLOCK_TAGS = {
    "html",
    "head",
    "body",
    "div",
    "p",
    "h1",
    "h2",
    "h3",
    "h4",
    "h5",
    "h6",
    "ul",
    "ol",
    "li",
    "table",
    "tbody",
    "thead",
    "tfoot",
    "tr",
    "td",
    "th",
    "form",
    "fieldset",
    "section",
    "article",
    "nav",
    "aside",
    "header",
    "footer",
    "main",
    "details",
    "summary",
    "blockquote",
    "pre",
    "script",
    "style",
    "link",
    "meta",
    "title",
}

# Теги, содержимое которых не трогаем
PRESERVE_TAGS = {"pre", "textarea", "script", "style"}


def format_html(html):
    # Защищаем содержимое pre/textarea/script/style
    preserved = []

    def save_block(m):
        preserved.append(m.group(0))
        return f"\x00BLOCK{len(preserved) - 1}\x00"

    html = re.sub(
        r"(<(?:pre|textarea|script|style)\b[^>]*>)(.*?)(</(?:pre|textarea|script|style)>)",
        save_block,
        html,
        flags=re.DOTALL | re.IGNORECASE,
    )

    # Убираем существующие переносы и лишние пробелы
    html = re.sub(r"[\r\n\t]+", " ", html)
    html = re.sub(r" {2,}", " ", html)

    # Перенос ПЕРЕД открывающими блочными тегами
    tags_pattern = "|".join(BLOCK_TAGS)
    html = re.sub(
        rf"(?<=>)\s*(<(?:{tags_pattern})\b)", r"\n\1", html, flags=re.IGNORECASE
    )

    # Перенос ПОСЛЕ закрывающих блочных тегов
    html = re.sub(rf"(</(?:{tags_pattern})>)\s*", r"\1\n", html, flags=re.IGNORECASE)

    # Перенос ПОСЛЕ самозакрывающихся тегов (meta, link, br, hr, img)
    html = re.sub(r"(<(?:meta|link)\b[^>]*>)\s*", r"\1\n", html, flags=re.IGNORECASE)

    # Перенос ПОСЛЕ <br> и <hr> (но br внутри кода не трогаем — они в preserved)
    html = re.sub(r"(<[Hh][Rr]\s*/?>)\s*", r"\1\n", html)

    # Убираем пустые строки (больше 2 переносов подряд)
    html = re.sub(r"\n{3,}", "\n\n", html)

    # Убираем пробелы в начале строк (но НЕ добавляем отступы)
    lines = html.split("\n")
    lines = [line.strip() for line in lines]
    html = "\n".join(lines)

    # Убираем пустые строки в начале и конце
    html = html.strip()

    # Восстанавливаем защищённые блоки
    for i, block in enumerate(preserved):
        html = html.replace(f"\x00BLOCK{i}\x00", block)

    return html


if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Использование:")
        print("  python html_format.py input.html [output.html]")
        print("  python html_format.py --dir ./folder")
        sys.exit(1)

    if sys.argv[1] == "--dir":
        folder = sys.argv[2] if len(sys.argv) > 2 else "."
        count = 0
        for root, _, files in os.walk(folder):
            for fname in files:
                if not fname.lower().endswith(".html"):
                    continue
                fpath = os.path.join(root, fname)
                with open(fpath, "r", encoding="utf-8-sig") as f:
                    original = f.read()
                result = format_html(original)
                with open(fpath, "w", encoding="utf-8-sig") as f:
                    f.write(result)
                count += 1
                print(f"  {os.path.relpath(fpath, folder)}")
        print(f"\nОтформатировано: {count} файлов")
    else:
        input_file = sys.argv[1]
        with open(input_file, "r", encoding="utf-8-sig") as f:
            html = f.read()

        result = format_html(html)

        if len(sys.argv) > 2:
            with open(sys.argv[2], "w", encoding="utf-8-sig") as f:
                f.write(result)
            print(f"Сохранено: {sys.argv[2]}")
        else:
            print(result)
