#!/usr/bin/env python3
"""
Python Unittest Suite for ANL Homepage E2E Verification
Queries live running Next.js server to assert DOM structure, text content, and theme attributes.
"""

import unittest
import os
import re
import time
import subprocess
import urllib.request

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEST_SERVER_URL = os.environ.get("TEST_SERVER_URL", "http://localhost:3000")

class TestANLHomepageE2E(unittest.TestCase):
    _server_proc = None
    _html_cache = {}

    @classmethod
    def setUpClass(cls):
        # Check if server is already responding at TEST_SERVER_URL
        is_ready = False
        try:
            with urllib.request.urlopen(f"{TEST_SERVER_URL}/", timeout=1) as resp:
                if resp.status == 200:
                    is_ready = True
        except Exception:
            is_ready = False

        if not is_ready:
            # Spawn local next start server
            cls._server_proc = subprocess.Popen(
                ["npm", "run", "start"],
                cwd=BASE_DIR,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True,
            )
            for _ in range(30):
                try:
                    with urllib.request.urlopen(f"{TEST_SERVER_URL}/", timeout=1) as resp:
                        if resp.status == 200:
                            is_ready = True
                            break
                except Exception:
                    time.sleep(0.5)

            if not is_ready:
                cls._server_proc.terminate()
                raise RuntimeError(f"Next.js server failed to become ready at {TEST_SERVER_URL}")

    @classmethod
    def tearDownClass(cls):
        if cls._server_proc:
            cls._server_proc.terminate()
            try:
                cls._server_proc.wait(timeout=5)
            except Exception:
                cls._server_proc.kill()

    def get_route_html(self, route):
        if route in self._html_cache:
            return self._html_cache[route]
        url = f"{TEST_SERVER_URL}{route}"
        req = urllib.request.Request(url, headers={"User-Agent": "E2ETestRunner"})
        with urllib.request.urlopen(req, timeout=10) as resp:
            html = resp.read().decode("utf-8")
            self._html_cache[route] = html
            return html

    def read_html(self, relative_path):
        route_map = {
            "index.html": "/",
            "members.html": "/members",
            "publications.html": "/publications",
            os.path.join("publications", "intl-journal-conf.html"): "/publications/intl-journal-conf",
            "publications/intl-journal-conf.html": "/publications/intl-journal-conf",
            os.path.join("publications", "domestic-journal-conf.html"): "/publications/domestic-journal-conf",
            "publications/domestic-journal-conf.html": "/publications/domestic-journal-conf",
            os.path.join("publications", "patent.html"): "/publications/patent",
            "publications/patent.html": "/publications/patent",
            "lectures.html": "/lectures",
            "standardization.html": "/standardization",
        }
        route = route_map.get(relative_path, f"/{relative_path}")
        return self.get_route_html(route)

    def test_01_home_page_structure(self):
        """TC-T1-F3: Verify Home page HTML content and semantic structures."""
        html = self.read_html("index.html")
        
        # 1. Brand & Header titles
        self.assertIn("ANL", html)
        self.assertIn("AI Agent Networking LAB", html)
        
        # 2. Research Areas keywords
        self.assertIn("Quick UDP Internet Connection (QUIC)", html)
        self.assertIn("Constrained Application Protocol (CoAP)", html)
        self.assertIn("Stream Control Transmission Protocol (SCTP)", html)
        self.assertIn("Tabu Search and Genetic Algorithm", html)

        # 3. Location / Address section
        self.assertIn("address", html.lower())
        self.assertIn("Kyungpook National University", html)
        self.assertIn("College of IT Engineering", html)
        self.assertIn("Prof. Seok-Joo Koh", html)
        self.assertIn("sjkoh@knu.ac.kr", html)

    def test_02_members_page_content(self):
        """TC-T1-F4: Verify Members page active members & alumni records."""
        html = self.read_html("members.html")
        
        # Professor profile
        self.assertIn("Prof. Seok-Joo Koh", html)
        self.assertIn("Seok-Joo Koh", html)
        self.assertIn("sjkoh@knu.ac.kr", html)
        
        # Sections & Degree formatting checks
        self.assertIn("LAB MEMBERS", html)
        self.assertIn("Active Researchers", html)
        self.assertIn("Graduates", html)
        self.assertIn("Ph. D. Candidate", html)
        self.assertIn("Project Editor", html)

    def test_03_publications_category_routes(self):
        """TC-T1-F5: Verify Publications categories live dynamic pages."""
        cats = [
            ("intl-journal-conf.html", "International Journal"),
            ("domestic-journal-conf.html", "Domestic Journal"),
            ("patent.html", "Patent"),
        ]
        for path_suffix, expected_text in cats:
            rel_path = os.path.join("publications", path_suffix)
            html = self.read_html(rel_path)
            self.assertIn(expected_text, html, f"Category route {path_suffix} missing '{expected_text}'")

    def test_04_lectures_page_content(self):
        """TC-T1-F6: Verify Lectures page HTML structure."""
        html = self.read_html("lectures.html")
        self.assertIn("Lectures", html)

    def test_05_standardization_page_content(self):
        """TC-T1-F6: Verify Standardization page standards bodies."""
        html = self.read_html("standardization.html")
        self.assertIn("Standardization", html)
        self.assertIn("IEC TC100", html)

    def test_06_theme_css_variables(self):
        """TC-T1-F2: Verify globals.css and built assets contain theme tokens."""
        globals_path = os.path.join(BASE_DIR, "app", "globals.css")
        with open(globals_path, "r", encoding="utf-8") as f:
            css = f.read()

        for token in ["--ink", "--ivory", "--paper", "--line", "--vermillion", "--cobalt"]:
            self.assertIn(token, css, f"Missing CSS variable {token} in globals.css")

    def test_07_research_projects_pageview(self):
        """TC-T1-F7: Verify Research Project PageView content in Home HTML."""
        html = self.read_html("index.html")
        
        # 1. Project PageView Title & Projects
        self.assertIn("Research Projects", html)
        self.assertIn("AI-RAN", html)
        self.assertIn("MCM", html)
        self.assertIn("MVQM", html)

        # 2. Standards track labels
        self.assertIn("National Research Foundation of Korea", html)
        self.assertIn("IEC/TC 100/WG 12 supported by KEIT", html)

        # 3. International Standardizations Section
        self.assertIn("International Standardizations", html)
        self.assertIn("IEC TC100: Multimedia Systems and Equipment", html)
        self.assertIn("ISO/IEC JTC1/SC6: Reliable Multicasting", html)

        # 4. Assert zero placeholder Funder labels
        self.assertNotIn("Funder:", html)

    def test_08_publications_highlights_and_category_nav(self):
        """TC-T1-F8: Verify 5 representative highlights and CategoryNav active border in Publications."""
        html = self.read_html("publications.html")

        # 1. Verify 5 designated representative publications
        expected_highlights = [
            "Globally Integrated Trust Authority (GITA) for Resource-Constrained Edge Devices in IoT and 6G",
            "Application Level Trust Authority (APPLETA) for Resource-Constrained Edge Devices in IoT and 6G",
            "mQUIC: Use of QUIC for Handover Support with Connection Migration in Wireless/Mobile Networks",
            "Use of QUIC for CoAP Transport in IoT Networks",
            "Use of QUIC for Mobile-Oriented Future Internet (Q-MOFI)",
        ]
        for title in expected_highlights:
            self.assertIn(title, html, f"Missing representative highlight publication: '{title}'")

        # 2. Verify Highlights heading & section
        self.assertIn("Highlights", html)
        self.assertIn("Categories", html)
        self.assertIn("(IoT Architecture &amp; Protocols, etc ...)", html)

        # 3. Verify category detail active card border & label
        patent_html = self.read_html(os.path.join("publications", "patent.html"))
        self.assertIn("border-2 border-cobalt-dark", patent_html)
        self.assertIn("Active View ●", patent_html)
        self.assertIn("Patent", patent_html)

    def test_09_footer_cite_and_brand_links(self):
        """TC-T1-F9: Verify Footer CITE abbreviation and brand/contact elements."""
        html = self.read_html("index.html")

        # 1. Institution link label CITE
        self.assertIn("<span>CITE</span>", html)
        self.assertIn("<span>KNU</span>", html)
        self.assertIn("<span>CSE</span>", html)

        # 2. Advisor contact info
        self.assertIn("Prof. Seok-Joo Koh", html)
        self.assertIn("sjkoh@knu.ac.kr", html)

    def test_10_subpage_layout_and_english_headers(self):
        """TC-T1-F10: Verify English page headers across all subpages."""
        subpages = [
            ("members.html", "LAB MEMBERS"),
            ("publications.html", "PUBLICATIONS"),
            ("lectures.html", "LECTURES"),
            ("standardization.html", "International Standardization"),
        ]
        for rel_path, expected_h1 in subpages:
            html = self.read_html(rel_path)
            self.assertIn(expected_h1, html, f"Subpage {rel_path} missing H1 '{expected_h1}'")

if __name__ == "__main__":
    unittest.main()
