#!/usr/bin/env python3
"""
Telegram Large File Downloader for Matrix File Editor Bot
Bypasses the 20MB file download limit using Telegram MTProto API.
Compatible with Python 3.6+ (non-interactive bot/user downloader).

API_ID: 26297341
API_HASH: 321267735440187bdd1f54fcb1f25612
"""

import sys
import os
import asyncio
import site

# Ensure user site-packages (~/.local/lib/python*/site-packages) are in sys.path
try:
    user_site = site.getusersitepackages()
    if user_site and user_site not in sys.path:
        sys.path.insert(0, user_site)
except Exception:
    pass

home_dir = os.path.expanduser("~")
for py_ver in ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]:
    p = os.path.join(home_dir, ".local", "lib", f"python{py_ver}", "site-packages")
    if os.path.exists(p) and p not in sys.path:
        sys.path.insert(0, p)

API_ID = 26297341
API_HASH = "321267735440187bdd1f54fcb1f25612"
BOT_TOKEN = "8977774604:AAHHwlNIYz9PtGCkRnmbliUENMIC304nYqA"

def run_async(coro):
    """Helper to run async coroutines compatible with Python 3.6+"""
    if hasattr(asyncio, "run"):
        return asyncio.run(coro)
    else:
        loop = asyncio.get_event_loop()
        return loop.run_until_complete(coro)

def clean_bad_session(session_path):
    """Removes corrupted or incomplete sqlite session files"""
    base = session_path.replace(".session", "")
    for ext in ["", ".session", ".session-journal"]:
        p = base + ext
        if os.path.exists(p):
            try:
                os.remove(p)
            except Exception:
                pass

def main():
    if len(sys.argv) < 3:
        print("Usage: python3 downloader.py <file_id> <output_path> [bot_token]")
        sys.exit(1)

    file_id = sys.argv[1]
    output_path = sys.argv[2]
    bot_token = sys.argv[3] if len(sys.argv) > 3 else BOT_TOKEN

    base_dir = os.path.dirname(os.path.abspath(__file__))
    temp_dir = os.path.join(base_dir, "temp")
    os.makedirs(os.path.dirname(output_path), exist_ok=True)
    os.makedirs(temp_dir, exist_ok=True)

    user_session_file = os.path.join(temp_dir, "user_session.session")
    use_user_session = os.path.exists(user_session_file) and os.path.getsize(user_session_file) > 0

    downloaded = False

    # 1. Try Pyrogram
    session_prefix = "pyro_user" if use_user_session else "pyro_bot"
    pyro_session = os.path.join(temp_dir, session_prefix)
    
    for attempt in range(2):
        try:
            from pyrogram import Client
            
            async def pyrogram_download():
                if use_user_session:
                    app = Client("pyro_user", api_id=API_ID, api_hash=API_HASH, workdir=temp_dir, no_updates=True)
                else:
                    app = Client("pyro_bot", api_id=API_ID, api_hash=API_HASH, bot_token=bot_token, workdir=temp_dir, no_updates=True)
                    
                async with app:
                    await app.download_media(file_id, file_name=output_path)
                return True

            run_async(pyrogram_download())
            downloaded = True
            print(f"SUCCESS_PYROGRAM ({'USER' if use_user_session else 'BOT'})")
            break

        except ImportError as e:
            print(f"Pyrogram import error: {e}")
            break
        except Exception as e:
            err_str = str(e)
            print(f"Pyrogram error (attempt {attempt+1}): {err_str}")
            # Clean partial/incomplete session file so Pyrogram re-authenticates with bot_token on next try
            clean_bad_session(pyro_session)
            if attempt == 1:
                break

    # 2. Try Telethon if Pyrogram failed or isn't installed
    if not downloaded:
        tele_session = os.path.join(temp_dir, "tele_user" if use_user_session else "tele_bot")
        try:
            from telethon import TelegramClient

            async def telethon_download():
                client = TelegramClient(tele_session, API_ID, API_HASH)
                if use_user_session:
                    await client.start()
                else:
                    await client.start(bot_token=bot_token)
                await client.download_media(file_id, file=output_path)
                await client.disconnect()
                return True

            run_async(telethon_download())
            downloaded = True
            print(f"SUCCESS_TELETHON ({'USER' if use_user_session else 'BOT'})")

        except ImportError as e:
            print(f"Telethon import error: {e}")
            print("ERROR: Neither 'pyrogram' nor 'telethon' python package is installed.")
            print("Install one of them using: pip install pyrogram tgcrypto  OR  pip install telethon")
            sys.exit(1)
        except Exception as e:
            print(f"Telethon error: {e}")
            sys.exit(1)

    if downloaded and os.path.exists(output_path) and os.path.getsize(output_path) > 0:
        sys.exit(0)
    else:
        print("ERROR: File download failed or resulted in 0 bytes.")
        sys.exit(1)

if __name__ == "__main__":
    main()
