#!/usr/bin/env python3
import types
import unittest
from pathlib import Path
import tempfile

import download


class DummyArgs:
    def __init__(self):
        self.post_type = ["posts", "reels"]
        self.flag_archive = True
        self.flag_skip = True
        self.flag_verbose = True


class DummyUser:
    def __init__(self):
        self.name = "jawz"
        self.sleep = 0
        self.directories = {"media": Path("/tmp/media"), "download": Path("/tmp/dl")}
        self.dbs = {"gallery": Path("/tmp/g.sqlite3"), "media": Path("/tmp/m.txt")}
        self.lists = {"push": Path("/tmp/instant.txt")}


class TestDownload(unittest.TestCase):
    def setUp(self) -> None:
        download.ARGS = DummyArgs()
        download.CONFIGS = {
            "users": [{"name": "jawz"}],
            "global": {},
            "comic": {"comic-list": "/tmp/comic.txt"},
        }
        self.orig_gallery = download.Gallery
        self.orig_video_command = download.video_command
        self.orig_run = download.run
        self.orig_db_connect = download.db.connect
        self.orig_db_add_link = download.db.add_link
        self.orig_save_comic = download.save_comic
        self.orig_make_handler = download._make_gallery_error_handler

    def tearDown(self) -> None:
        download.Gallery = self.orig_gallery
        download.video_command = self.orig_video_command
        download.run = self.orig_run
        download.db.connect = self.orig_db_connect
        download.db.add_link = self.orig_db_add_link
        download.save_comic = self.orig_save_comic
        download._make_gallery_error_handler = self.orig_make_handler

    def test_parse_instagram(self):
        res = download.parse_instagram("https://instagram.com/user")
        self.assertEqual(res, ["-o", "include=posts,reels"])
        res2 = download.parse_instagram("https://x.com/user")
        self.assertEqual(res2, [])

    def test_video_command(self):
        v = download.Video()
        v.link = "https://youtu.be/abc"
        v.dest = "/tmp"
        cmd = download.video_command(v)
        self.assertIn("yt-dlp", cmd[0])
        self.assertIn("https://youtu.be/abc", cmd)

        v2 = download.Video()
        v2.link = "https://music.youtube.com/watch?v=xyz"
        v2.dest = "/tmp"
        v2.use_archive = False
        cmd2 = download.video_command(v2)
        self.assertIn("--audio-format", cmd2)

    def test_push_manager_routing(self):
        user = DummyUser()

        captured = {"gallery": [], "video": [], "comic": [], "other": []}

        def fake_generate(self, *args, **kwargs):
            return None

        def fake_run(self, *args, **kwargs):
            link = getattr(self, "link", "")
            if "mangadex" in link:
                captured["comic"].append(link)
            elif "x.com" in link:
                captured["gallery"].append(link)
            else:
                captured["other"].append(link)

        def fake_video_command(video):
            captured["video"].append(video.link)
            return ["echo", "ok"]

        # Patch Gallery methods and video_command/run
        class FakeGallery(self.orig_gallery):
            def generate_command(self, *args, **kwargs):
                return fake_generate(self, *args, **kwargs)

            def run_command(self, *args, **kwargs):
                return fake_run(self, *args, **kwargs)

        download.Gallery = FakeGallery
        download.video_command = fake_video_command
        download.run = lambda *args, **kwargs: None
        download.save_comic = lambda *_args, **_kwargs: None
        download._make_gallery_error_handler = lambda *_args, **_kwargs: None

        links = [
            "https://x.com/someuser",
            "https://youtu.be/abc",
            "https://mangadex.org/title/123",
            "https://example.com/page",
        ]

        # Disable DB write path for this test
        class FakeConn:
            def __enter__(self):
                return self

            def __exit__(self, exc_type, exc, tb):
                return False

            def commit(self):
                return None

        download.db.connect = lambda *a, **k: FakeConn()
        download.db.add_link = lambda *a, **k: {"status": "added"}

        download.push_manager(user, links=links)

        self.assertEqual(len(captured["gallery"]), 1)
        self.assertEqual(len(captured["video"]), 1)
        self.assertEqual(len(captured["comic"]), 1)
        self.assertEqual(len(captured["other"]), 1)

        # restore handled in tearDown


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