import importlib.util
import sys
import threading
import time
from pathlib import Path


MODULE_DIR = Path(__file__).parents[1] / "tools" / "gptbridge"
BROWSER_SPEC = importlib.util.spec_from_file_location("browser", MODULE_DIR / "browser.py")
browser = importlib.util.module_from_spec(BROWSER_SPEC)
assert BROWSER_SPEC.loader
BROWSER_SPEC.loader.exec_module(browser)
sys.modules["browser"] = browser
CHAT_SPEC = importlib.util.spec_from_file_location("chat", MODULE_DIR / "chat.py")
chat = importlib.util.module_from_spec(CHAT_SPEC)
assert CHAT_SPEC.loader
sys.modules["chat"] = chat
CHAT_SPEC.loader.exec_module(chat)


def test_append_unique_file_removes_duplicate(tmp_path):
    first = tmp_path / "first.zip"
    duplicate = tmp_path / "duplicate.zip"
    first.write_bytes(b"same archive")
    duplicate.write_bytes(b"same archive")
    reply = chat.Reply(text="", files=[first])

    chat._append_unique_file(reply, duplicate)

    assert reply.files == [first]
    assert not duplicate.exists()


def test_harvest_skips_duplicate_download_button_when_file_link_exists(tmp_path, monkeypatch):
    class Browser:
        def sync_script(self, *_args):
            return {
                "text": "done",
                "url": "https://chatgpt.com/c/test",
                "files": [{"src": "https://example.test/theme", "name": "theme.zip"}],
                "downloads": ["Download theme.zip"],
            }

    monkeypatch.setattr(chat, "_fetch_blob", lambda *_args: {
        "data": "data:application/zip;base64,UEsDBA==",
        "disposition": "",
    })
    monkeypatch.setattr(
        chat, "_download_button",
        lambda *_args: (_ for _ in ()).throw(AssertionError("duplicate button clicked")),
    )

    reply = chat.harvest(Browser(), tmp_path, "generated", "theme")

    assert [path.name for path in reply.files] == ["theme.zip"]


def test_download_button_waits_for_partial_file(tmp_path, monkeypatch):
    downloads = tmp_path / "downloads"
    output = tmp_path / "output"
    downloads.mkdir()
    output.mkdir()
    monkeypatch.setattr(chat, "DOWNLOAD_DIR", downloads)
    final = downloads / "theme.zip"
    partial = downloads / "theme.random.zip.part"
    payload = b"PK\x03\x04complete archive"
    writer = None

    class Browser:
        def sync_script(self, *_args):
            nonlocal writer
            final.touch()

            def finish_download():
                time.sleep(0.2)
                partial.write_bytes(payload[:8])
                time.sleep(0.6)
                partial.write_bytes(payload)
                time.sleep(0.6)
                partial.replace(final)

            writer = threading.Thread(target=finish_download)
            writer.start()
            return True

    result = chat._download_button(Browser(), 0, "Download theme.zip", output, timeout=5)
    writer.join()

    assert result == output / "theme.zip"
    assert result.read_bytes() == payload
    assert not partial.exists()
