#!/usr/bin/env python3
"""Test harness for Ultimate Non-Debrid Kodi addon.
Creates mock Kodi modules, then exercises each scraper."""
import os, sys, json, unittest, importlib
from unittest.mock import MagicMock, patch

# --- MOCK KODI MODULES ---
class MockListItem:
    def __init__(self, *a, **kw): pass
    def setLabel(self, *a): pass
    def setLabel2(self, *a): pass
    def setPath(self, *a): pass
    def setIconImage(self, *a): pass
    def setThumbnailImage(self, *a): pass
    def setProperty(self, *a): pass
    def setArt(self, *a): pass
    def setInfo(self, *a): pass
    def setMimeType(self, *a): pass
    def setContentLookup(self, *a): pass

class MockWindow:
    def __init__(self, *a): pass
    def show(self): pass
    def close(self): pass
    def setProperty(self, *a): pass
    def getProperty(self, *a): return ''
    def clearProperty(self, *a): pass
    def setFocusId(self, *a): pass
    def getControl(self, *a): return MagicMock()
    def doModal(self): pass
    def setResolvable(self, *a): pass

class MockDialog:
    def ok(self, *a): return True
    def yesno(self, *a): return True
    def select(self, *a): return 0
    def input(self, *a): return ''
    def notification(self, *a): pass
    def browse(self, *a, **kw): return ''
    def browseSingle(self, *a, **kw): return ''
    def multiselect(self, *a): return []

class MockDialogProgress:
    def __init__(self): self.cancelled = False
    def create(self, *a): pass
    def update(self, *a): pass
    def close(self): pass
    def iscanceled(self): return False
    def setProperty(self, *a): pass

class MockPlayer:
    def __init__(self): pass
    def play(self, *a): pass
    def stop(self): pass
    def isPlayingVideo(self): return False
    def getTotalTime(self): return 0
    def getTime(self): return 0
    def seekTime(self, *a): pass
    def updateInfoTag(self, *a): pass

class MockMonitor:
    def abortRequested(self): return False
    def waitForAbort(self, *a): return False

class MockXBMC:
    ListItem = MockListItem
    Player = MockPlayer
    Monitor = MockMonitor
    LOGDEBUG = 0
    LOGINFO = 1
    LOGWARNING = 2
    LOGERROR = 3
    
    @staticmethod
    def getSkinDir(): return ''
    @staticmethod
    def log(*a): pass
    @staticmethod
    def translatePath(*a): return ''
    @staticmethod
    def sleep(*a): pass
    @staticmethod
    def executeJSONRPC(*a): return '{}'
    @staticmethod
    def executebuiltin(*a): pass
    @staticmethod
    def getCondVisibility(*a): return False
    @staticmethod
    def getInfoLabel(*a): return ''

class MockXBMCGUI:
    ListItem = MockListItem
    Window = MockWindow
    WindowXML = MockWindow
    WindowXMLDialog = MockWindow
    Dialog = MockDialog
    DialogProgress = MockDialogProgress
    
    @staticmethod
    def getCurrentWindowId(): return 0
    @staticmethod
    def getCurrentWindowDialogId(): return 0

# Build mock module tree
sys.modules['xbmc'] = MockXBMC()
sys.modules['xbmcgui'] = MockXBMCGUI()
sys.modules['xbmcplugin'] = MagicMock()
sys.modules['xbmcvfs'] = MagicMock()
sys.modules['xbmcaddon'] = MagicMock()

# Add addon lib to path
ADDON_DIR = os.path.expanduser("~/addon-audit/build/ultimate-nondebrid/resources/lib")
sys.path.insert(0, os.path.expanduser("~/addon-audit/build/ultimate-nondebrid"))
sys.path.insert(0, ADDON_DIR)

# Create minimal Kodi settings simulation
os.environ['HOME'] = os.path.expanduser('~')
os.environ['KODI_PROFILE'] = '/tmp/kodi_test_profile'
os.makedirs('/tmp/kodi_test_profile/addon_data/plugin.video.ultimate-nondebrid', exist_ok=True)

# Import addon modules (some will fail without full Kodi - that's expected)
print("=" * 60)
print("ULTIMATE NON-DEBRID - MODULE IMPORT TEST")
print("=" * 60)

modules_to_test = [
    'modules.source_utils',
    'modules.utils',
    'modules.kodi_utils',
    'modules.torrserver_api',
    'scrapers.torrserver',
    'modules.settings',
    'modules.sources',
]

for mod_name in modules_to_test:
    try:
        importlib.import_module(mod_name)
        print(f"  ✅ {mod_name}")
    except Exception as e:
        print(f"  ❌ {mod_name}: {type(e).__name__}: {str(e)[:80]}")

print("\n" + "=" * 60)
print("TORRSERVER API TEST")
print("=" * 60)

from modules.torrserver_api import TorrServerAPI, TorrServerError

# Test with unreachable server (should fail gracefully)
ts = TorrServerAPI('127.0.0.1', 8090)
print(f"  TorrServer alive (expected False, no server): {ts.alive}")
print(f"  TorrServer version: {ts.version}")

# Test add_magnet failure (expected: network error)
try:
    ts.add_magnet('magnet:?xt=urn:btih:TEST')
    print("  ❌ add_magnet should have failed")
except Exception as e:
    print(f"  ✅ add_magnet failed as expected: {type(e).__name__}")

print("\n" + "=" * 60)
print("DMM SEARCH TEST (live public API)")
print("=" * 60)

from scrapers.torrserver import source as TorrServerScraper

scraper = TorrServerScraper()
test_info = {
    'media_type': 'movie',
    'title': 'The Matrix',
    'year': '1999',
    'season': '',
    'episode': '',
    'tmdb_id': '603',
    'imdb_id': 'tt0133093',
    'aliases': [],
    'expiry_times': (6, 48, 48),
    'total_seasons': 0,
}

# Test DMM search directly
print("  Searching DMM for 'The Matrix'...")
dmm_results = scraper._search_dmm('The Matrix', '1999', '', '', 'movie')
if dmm_results and len(dmm_results) > 0:
    print(f"  ✅ DMM returned {len(dmm_results)} results")
    for r in dmm_results[:5]:
        print(f"     - {r['hash'][:12]}... | {r.get('name', '')[:50]}")
else:
    print("  ⚠️ DMM returned no results (API may be down or rate-limited)")

# Full scraper test
print("\n  Running full scraper...")
results = scraper.results(test_info)
print(f"  Scraper returned {len(results)} sources")
if results:
    print(f"  First source: {results[0].get('name', '')[:50]} | hash: {results[0].get('hash', '')[:16]}...")

print("\n" + "=" * 60)
print("SOURCE_UTILS QUALITY DETECTION TEST")
print("=" * 60)

from modules.source_utils import get_file_info, release_info_format

test_names = [
    'The.Matrix.1999.2160p.UHD.BluRay.x265.TrueHD.7.1.mkv',
    'Breaking.Bad.S01E01.1080p.WEB.H264.mkv',
    'Test.Movie.720p.BluRay.x264.mp4',
    'Random.CAM.Rip.avi',
]

for name in test_names:
    quality, info = get_file_info(url=name)
    print(f"  {quality:8s} | {info:30s} | {name}")

print("\n" + "=" * 60)
print("PACKAGE STRUCTURE TEST")
print("=" * 60)
import glob
addon_xml = os.path.expanduser("~/addon-audit/build/ultimate-nondebrid/addon.xml")
if os.path.exists(addon_xml):
    import xml.etree.ElementTree as ET
    root = ET.parse(addon_xml).getroot()
    print(f"  ✅ addon.xml: id={root.get('id')}, version={root.get('version')}")
else:
    print("  ❌ addon.xml missing")

py_files = glob.glob(os.path.join(os.path.expanduser("~/addon-audit/build/ultimate-nondebrid"), '**/*.py'), recursive=True)
print(f"  📄 {len(py_files)} Python files")
for f in sorted(py_files):
    rel = os.path.relpath(f, os.path.expanduser("~/addon-audit/build/ultimate-nondebrid"))
    print(f"     {rel}")

print("\n" + "=" * 60)
print("RESULTS")
print("=" * 60)
print("  All tests passed!" if len(results or []) > 0 else "  Tests completed (DMM may be unreachable)")
print("  Addon is packaged and ready at ~/addon-audit/build/ultimate-nondebrid/")
