#!/usr/bin/env python3
import os
import subprocess
from concurrent.futures import ThreadPoolExecutor, as_completed
import threading

# Path to the TwitchDownloaderCLI DLL
CLI = [
    "dotnet",
    "/zfszero/fuwa/TwitchDownloader/TwitchDownloaderCLI/out/TwitchDownloaderCLI.dll",
]

# Files containing URL lists
FILES = [
    "all_videos.txt",
    "highlights.txt",
    "past_broadcasts.txt",
    "uploads.txt",
]

# Number of parallel downloads
MAX_WORKERS = 4

# Thread-safe counter and lock
lock = threading.Lock()
tasks = []

# Load tasks from files
for fname in FILES:
    if not os.path.isfile(fname):
        continue
    with open(fname, "r") as f:
        for line in f:
            url = line.strip()
            if url:
                tasks.append((fname, url))

total = len(tasks)
completed = 0

def process(source_file, url):
    global completed
    # Determine output directory (filename sans .txt)
    dir_name = source_file[:-4]
    os.makedirs(dir_name, exist_ok=True)

    # Prepare outputs and failure log path
    video_id = url.rstrip("/").split("/")[-1]
    video_out = os.path.join(dir_name, f"{video_id}.mp4")
    chat_out = os.path.join(dir_name, f"{video_id}_chat.json")
    failed_log = os.path.join(dir_name, "failed.txt")

    with lock:
        completed += 1
        print(f"[{completed}/{total}] Starting: {url}")

    try:
        # Download video if not already present
        if not os.path.exists(video_out):
            subprocess.run(
                CLI + ["videodownload", "--id", url, "--output", video_out],
                check=True,
            )
        else:
            print(f"    Video exists, skipping: {video_out}")

        # Download chat if not already present
        if not os.path.exists(chat_out):
            subprocess.run(
                CLI + ["chatdownload", "--id", url, "--output", chat_out],
                check=True,
            )
        else:
            print(f"    Chat exists, skipping: {chat_out}")

    except subprocess.CalledProcessError:
        print(f"    Failed download: {url}")
        with open(failed_log, "a") as fw:
            fw.write(url + "\n")

    with lock:
        print(f"[{completed}/{total}] Finished: {url}")

def main():
    if total == 0:
        print("No URLs found in any of the txt files.")
        return

    print(f"Total tasks: {total}. Using {MAX_WORKERS} threads.")

    with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
        futures = [executor.submit(process, sf, url) for sf, url in tasks]
        for _ in as_completed(futures):
            pass

    print("All tasks completed.")

if __name__ == "__main__":
    main()
