import os
import re
from urllib.request import urlopen, Request
from urllib.error import URLError
from bs4 import BeautifulSoup

SPEC_DIR = os.path.join(
    os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
    "specifications",
)

ROOT_URL = "https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/"

# Targets to download
TARGETS = ['BAP', 'CAP', 'TMAP', 'HAP', 'PBP', 'MCP', 'CCP', 'MICP', 'VCP', 'ASCS', 'PACS', 'CSIS', 'CSIP', 'BASS', 'AICS']

def get_all_index_links():
    print(f"Fetching directory listing from {ROOT_URL}...")
    headers = {'User-Agent': 'Mozilla/5.0'}
    try:
        req = Request(ROOT_URL, headers=headers)
        with urlopen(req, timeout=30) as response:
            html_content = response.read()
            soup = BeautifulSoup(html_content, 'html.parser')
            links = []
            for a in soup.find_all('a'):
                href = a.get('href', '')
                if "index-en.html" in href:
                    links.append(href)
            return links
    except URLError as e:
        print(f"Error fetching root directory: {e}")
        return []

def match_target(path, acronym):
    pattern = re.compile(rf"(?:^|/|_|-)({acronym})(?:[._-]|html5)", re.IGNORECASE)
    return bool(pattern.search(path))

def parse_version(path, acronym):
    pattern = re.compile(rf"{acronym}_v(\d+(?:[.-]\d+)*)", re.IGNORECASE)
    match = pattern.search(path)
    if match:
        return match.group(1).replace('-', '.')
    return "0.0"

def get_latest_link(links, acronym):
    target_links = [l for l in links if match_target(l, acronym)]
    if not target_links:
        return None

    timestamp_pattern = re.compile(r"_(\d{10})/")

    def sort_key(path):
        version_str = parse_version(path, acronym)
        version_parts = []
        for x in version_str.split('.'):
            try:
                version_parts.append(int(x))
            except ValueError:
                version_parts.append(0)

        timestamp_match = timestamp_pattern.search(path)
        timestamp = int(timestamp_match.group(1)) if timestamp_match else 0

        return (version_parts, timestamp)

    sorted_links = sorted(target_links, key=sort_key, reverse=True)
    return sorted_links[0]

def download_spec(name, relative_url):
    url = ROOT_URL + relative_url
    print(f"Downloading {name} from {url}...")
    headers = {'User-Agent': 'Mozilla/5.0'}
    try:
        req = Request(url, headers=headers)
        with urlopen(req, timeout=30) as response:
            html_content = response.read()

            # Create spec dir if not exists
            os.makedirs(SPEC_DIR, exist_ok=True)

            # Save HTML
            html_path = os.path.join(SPEC_DIR, f"{name}.html")
            with open(html_path, 'wb') as f:
                f.write(html_content)
            print(f"Saved HTML to {html_path}")

            # Save Text/Markdown for searching
            soup = BeautifulSoup(html_content, 'html.parser')
            text_content = soup.get_text(separator='\n', strip=True)

            md_path = os.path.join(SPEC_DIR, f"{name}.md")
            with open(md_path, 'w', encoding='utf-8') as f:
                f.write(text_content)
            print(f"Saved Markdown to {md_path}")

    except URLError as e:
        print(f"Error downloading {name}: {e}")
    except Exception as e:
        print(f"An error occurred: {e}")

def main():
    links = get_all_index_links()
    if not links:
        print("No links found.")
        return

    for target in TARGETS:
        latest_link = get_latest_link(links, target)
        if latest_link:
            version = parse_version(latest_link, target)
            name = f"{target}_v{version}" if version != "0.0" else target
            if version == "0.0":
                match = re.search(rf"(\d+)-{target}-html5", latest_link, re.IGNORECASE)
                if match:
                    name = f"{target}_ID_{match.group(1)}"

            download_spec(name, latest_link)
        else:
            print(f"No link found for {target}")

if __name__ == "__main__":
    main()
