"""
Tests fuer das BreakPilot Studio Frontend (studio.py)

Testet CSS-Regeln und HTML-Struktur des Frontends.

Nach dem Refactoring (2024-12-16) werden CSS und JS aus separaten Dateien geladen:
- CSS: frontend/static/css/studio.css
- JS: frontend/static/js/studio.js
- HTML: frontend/templates/studio.html
"""
import pytest
import re
import sys
import os
from pathlib import Path

# Add parent directory to path for imports
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# Pfade zu den statischen Dateien
FRONTEND_DIR = Path(__file__).parent.parent / "frontend"
STATIC_CSS = FRONTEND_DIR / "static" / "css" / "studio.css"
STATIC_JS = FRONTEND_DIR / "static" / "js" / "studio.js"
TEMPLATE_HTML = FRONTEND_DIR / "templates" / "studio.html"


class TestStudioRefactoringStructure:
    """Tests fuer die refactored Dateistruktur."""

    def test_css_file_exists(self):
        """Testet, dass die CSS-Datei existiert."""
        assert STATIC_CSS.exists(), f"CSS-Datei nicht gefunden: {STATIC_CSS}"

    def test_js_file_exists(self):
        """Testet, dass die JS-Datei existiert."""
        assert STATIC_JS.exists(), f"JS-Datei nicht gefunden: {STATIC_JS}"

    def test_html_template_exists(self):
        """Testet, dass das HTML-Template existiert."""
        assert TEMPLATE_HTML.exists(), f"HTML-Template nicht gefunden: {TEMPLATE_HTML}"

    def test_html_references_css(self):
        """Testet, dass das HTML-Template die CSS-Datei referenziert."""
        html_content = TEMPLATE_HTML.read_text(encoding="utf-8")
        assert '/static/css/studio.css' in html_content, \
            "HTML-Template muss CSS-Datei referenzieren"

    def test_html_references_js(self):
        """Testet, dass das HTML-Template die JS-Datei referenziert."""
        html_content = TEMPLATE_HTML.read_text(encoding="utf-8")
        assert '/static/js/studio.js' in html_content, \
            "HTML-Template muss JS-Datei referenzieren"

    def test_studio_py_loads_template(self):
        """Testet, dass studio.py das Template laedt."""
        from frontend.studio import app_ui
        html = app_ui()
        # Nach Refactoring sollte HTML aus Template kommen
        assert '<!DOCTYPE html>' in html or 'BreakPilot' in html, \
            "studio.py muss HTML-Inhalt zurueckgeben"


class TestStudioSidebarCSS:
    """Tests fuer die Sidebar CSS-Eigenschaften."""

    @pytest.fixture
    def studio_css(self):
        """Laedt den CSS-Inhalt aus der separaten CSS-Datei.

        Nach dem CSS-Refactoring sind die Styles modularisiert.
        Sidebar-Styles befinden sich in modules/admin/sidebar.css.
        """
        # Primaer: Modularisierte Sidebar-Datei
        sidebar_css_path = FRONTEND_DIR / "static" / "css" / "modules" / "admin" / "sidebar.css"
        if sidebar_css_path.exists():
            return sidebar_css_path.read_text(encoding="utf-8")

        # Fallback: Legacy studio.css
        return STATIC_CSS.read_text(encoding="utf-8")

    @pytest.fixture
    def studio_html(self):
        """Laedt den HTML-Inhalt aus dem Template."""
        return TEMPLATE_HTML.read_text(encoding="utf-8")

    def test_sidebar_has_overflow_y_auto(self, studio_css):
        """
        Testet, dass die Sidebar vertikal scrollbar ist.

        Regression Test: Die Sidebar muss overflow-y: auto haben,
        damit GPU Start/Stop Buttons sichtbar sind wenn viele
        Kostenzeilen vorhanden sind.
        """
        # Suche nach .sidebar CSS-Block
        sidebar_css_pattern = r'\.sidebar\s*\{[^}]*\}'
        sidebar_css_match = re.search(sidebar_css_pattern, studio_css, re.DOTALL)

        assert sidebar_css_match is not None, "Sidebar CSS-Block nicht gefunden"

        sidebar_css = sidebar_css_match.group(0)

        # Pruefe dass overflow-y: auto vorhanden ist
        assert 'overflow-y: auto' in sidebar_css or 'overflow-y:auto' in sidebar_css, \
            "Sidebar muss overflow-y: auto haben fuer Scrollbarkeit"

    def test_sidebar_has_overflow_x_hidden(self, studio_css):
        """
        Testet, dass die Sidebar horizontal nicht scrollbar ist.
        """
        sidebar_css_pattern = r'\.sidebar\s*\{[^}]*\}'
        sidebar_css_match = re.search(sidebar_css_pattern, studio_css, re.DOTALL)

        assert sidebar_css_match is not None, "Sidebar CSS-Block nicht gefunden"

        sidebar_css_block = sidebar_css_match.group(0)

        # Pruefe dass overflow-x: hidden vorhanden ist
        assert 'overflow-x: hidden' in sidebar_css_block or 'overflow-x:hidden' in sidebar_css_block, \
            "Sidebar muss overflow-x: hidden haben"

    def test_sidebar_does_not_have_overflow_hidden_only(self, studio_css):
        """
        Testet, dass die Sidebar NICHT nur overflow: hidden hat.

        Regression Test: overflow: hidden wuerde verhindern,
        dass Benutzer zu den GPU-Buttons scrollen koennen.
        """
        sidebar_css_pattern = r'\.sidebar\s*\{[^}]*\}'
        sidebar_css_match = re.search(sidebar_css_pattern, studio_css, re.DOTALL)

        assert sidebar_css_match is not None, "Sidebar CSS-Block nicht gefunden"

        sidebar_css_block = sidebar_css_match.group(0)

        # Pruefe dass nicht einfach "overflow: hidden" steht (ohne x/y Spezifikation)
        # Erlaubt sind: overflow-x: hidden, overflow-y: hidden, aber nicht nur "overflow: hidden"
        has_overflow_hidden_only = re.search(r'overflow\s*:\s*hidden', sidebar_css_block) and \
                                   not re.search(r'overflow-[xy]\s*:', sidebar_css_block)

        assert not has_overflow_hidden_only, \
            "Sidebar darf nicht nur 'overflow: hidden' haben - GPU Buttons waeren nicht erreichbar"


@pytest.mark.skip(reason="vast.ai GPU UI not yet implemented in frontend template")
class TestStudioGPUControls:
    """Tests fuer die GPU-Kontrollelemente.

    HINWEIS: Diese Tests sind fuer zukuenftige vast.ai GPU-UI-Elemente.
    Die Backend-API existiert bereits (infra/vast_power.py), aber die
    Frontend-UI-Elemente wurden noch nicht in studio.html implementiert.
    """

    @pytest.fixture
    def studio_html(self):
        """Laedt den HTML-Inhalt aus dem Template."""
        return TEMPLATE_HTML.read_text(encoding="utf-8")

    def test_gpu_start_button_exists(self, studio_html):
        """Testet, dass der GPU Start-Button existiert."""
        assert 'id="btn-vast-start"' in studio_html, \
            "GPU Start-Button (btn-vast-start) nicht gefunden"

    def test_gpu_stop_button_exists(self, studio_html):
        """Testet, dass der GPU Stop-Button existiert."""
        assert 'id="btn-vast-stop"' in studio_html, \
            "GPU Stop-Button (btn-vast-stop) nicht gefunden"

    def test_gpu_status_badge_exists(self, studio_html):
        """Testet, dass der GPU Status-Badge existiert."""
        assert 'id="vast-status-badge"' in studio_html, \
            "GPU Status-Badge nicht gefunden"

    def test_gpu_buttons_are_in_sidebar(self, studio_html):
        """
        Testet, dass die GPU-Buttons innerhalb der Sidebar sind.
        """
        # Finde die Sidebar-Sektion
        sidebar_pattern = r'<aside[^>]*class="[^"]*sidebar[^"]*"[^>]*>.*?</aside>'
        sidebar_match = re.search(sidebar_pattern, studio_html, re.DOTALL)

        assert sidebar_match is not None, "Sidebar nicht gefunden"

        sidebar_content = sidebar_match.group(0)

        # Pruefe dass GPU-Buttons in der Sidebar sind
        assert 'btn-vast-start' in sidebar_content, \
            "GPU Start-Button muss in der Sidebar sein"
        assert 'btn-vast-stop' in sidebar_content, \
            "GPU Stop-Button muss in der Sidebar sein"

    def test_gpu_cost_elements_exist(self, studio_html):
        """Testet, dass die Kostenanzeige-Elemente existieren."""
        required_elements = [
            'vast-cost-hour',      # Kosten pro Stunde
            'vast-credit',         # Budget/Credit
            'vast-session-cost',   # Session-Kosten
        ]

        for element_id in required_elements:
            assert f'id="{element_id}"' in studio_html, \
                f"Kostenelement {element_id} nicht gefunden"


@pytest.mark.skip(reason="vast.ai GPU UI not yet implemented in frontend template")
class TestStudioVastButtons:
    """Tests fuer die vast.ai Button-Styles.

    HINWEIS: vast.ai UI-Elemente wurden noch nicht implementiert.
    """

    @pytest.fixture
    def studio_html(self):
        """Laedt den HTML-Inhalt aus dem Template."""
        return TEMPLATE_HTML.read_text(encoding="utf-8")

    @pytest.fixture
    def studio_css(self):
        """Laedt den CSS-Inhalt aus der separaten CSS-Datei."""
        return STATIC_CSS.read_text(encoding="utf-8")

    def test_vast_buttons_container_exists(self, studio_html):
        """Testet, dass der vast-buttons Container existiert."""
        assert 'class="vast-buttons"' in studio_html, \
            "vast-buttons Container nicht gefunden"

    def test_vast_buttons_css_exists(self, studio_css):
        """Testet, dass CSS fuer .vast-buttons existiert."""
        assert '.vast-buttons' in studio_css, \
            "CSS fuer .vast-buttons nicht gefunden"


class TestStudioStaticFilesIntegration:
    """Integration Tests fuer Static Files Serving."""

    def test_main_py_mounts_static_files(self):
        """Testet, dass main.py die Static Files korrekt mountet."""
        main_py = Path(__file__).parent.parent / "main.py"
        main_content = main_py.read_text(encoding="utf-8")

        assert 'StaticFiles' in main_content, \
            "main.py muss StaticFiles importieren"
        assert 'app.mount("/static"' in main_content or "app.mount('/static'" in main_content, \
            "main.py muss /static mounten"

    def test_static_directory_structure(self):
        """Testet, dass die Static-Verzeichnisstruktur korrekt ist."""
        static_dir = FRONTEND_DIR / "static"
        assert static_dir.exists(), "static/ Verzeichnis muss existieren"
        assert (static_dir / "css").exists(), "static/css/ Verzeichnis muss existieren"
        assert (static_dir / "js").exists(), "static/js/ Verzeichnis muss existieren"


if __name__ == '__main__':
    pytest.main([__file__, '-v'])
