# -*- coding: utf-8 -*-
from __future__ import unicode_literals

"""Worker assíncrono de legendas do OnePlay Matrix.

É iniciado por ``RunScript`` somente depois que a rota VOD já entregou a fonte
para o Kodi. Não recebe URL da mídia, token, Cookie nem Authorization: usa um
job local de curta duração com IDs públicos e referências loopback opacas.
"""

import os
import re
import sys
import time

try:
    from kodi_six import xbmc, xbmcaddon
except ImportError:
    import xbmc
    import xbmcaddon

ADDON_ID = 'plugin.video.OnePlay.Matrix'
PLAYER_WAIT_SECS = 20.0
WAIT_STEP_SECS = 0.15


def _addon():
    try:
        return xbmcaddon.Addon(ADDON_ID)
    except Exception:
        return xbmcaddon.Addon()


def _addon_path(addon):
    try:
        path = addon.getAddonInfo('path')
        if path and path not in sys.path:
            sys.path.insert(0, path)
        return path
    except Exception:
        return ''


def _parse_job_id():
    for value in sys.argv[1:]:
        candidate = str(value or '').strip().lower()
        if re.match(r'^[a-f0-9]{16,64}$', candidate):
            return candidate
    return ''


def _is_playing_video(player):
    try:
        return bool(player.isPlayingVideo() or player.isPlaying())
    except Exception:
        return False


def _matches_expected_player(player, job):
    """Evita anexar legenda de uma escolha anterior em uma nova reprodução."""
    session_ref = str(job.get('playback_session') or '')
    item_key = str(job.get('playback_item') or '')
    if str(job.get('stream_kind') or '').lower() == 'dash':
        # DASH segue direto ao InputStream Adaptive e não carrega a referência
        # loopback ``vs/vi``. O job nasce após a seleção; só anexa com vídeo
        # efetivamente ativo, preservando a compatibilidade deste caminho.
        return True, 'dash_sem_proxy'
    if not session_ref or not item_key:
        # Compatibilidade para links legados sem proxy local. O worker é
        # disparado logo após a seleção; só anexa quando há vídeo ativo.
        return True, 'sem_referencia_loopback'
    try:
        playing_file = str(player.getPlayingFile() or '')
    except Exception:
        playing_file = ''
    if ('vs={}'.format(session_ref) in playing_file and
            'vi={}'.format(item_key) in playing_file):
        return True, 'sessao_confirmada'
    if playing_file:
        return False, 'sessao_trocada'
    return False, 'aguardando_caminho'


def _wait_for_expected_player(job, monitor):
    started = time.time()
    while not monitor.abortRequested() and (time.time() - started) < PLAYER_WAIT_SECS:
        player = xbmc.Player()
        if _is_playing_video(player):
            matches, state = _matches_expected_player(player, job)
            if matches:
                return player, 'confirmado', int((time.time() - started) * 1000)
            if state == 'sessao_trocada':
                return None, state, int((time.time() - started) * 1000)
        try:
            if monitor.waitForAbort(WAIT_STEP_SECS):
                break
        except Exception:
            xbmc.sleep(int(WAIT_STEP_SECS * 1000))
    return None, 'timeout_player', int((time.time() - started) * 1000)


def main():
    addon = _addon()
    _addon_path(addon)
    from resources.lib import subtitles
    from resources.lib.common import log_debug, log_exception, log_event
    try:
        from resources.lib import dns as dns_helper
        dns_helper.apply_configured_override()
    except Exception:
        # Legenda segue opcional: falha de override DNS nunca deve impedir o
        # player já entregue nem derrubar o worker.
        pass

    job_id = _parse_job_id()
    if not job_id:
        return
    job = subtitles.load_async_subtitle_job(job_id, addon=addon)
    if not job:
        log_debug('Worker de legenda encerrado: job ausente/expirado.', addon=addon, component='Subtitles')
        return

    started = time.time()
    try:
        log_event('Subtitles', 'worker_inicio', addon=addon,
                  job=job_id[:8], modo='background', tipo=job.get('media_type', ''))
        # O cache já foi limpo pela rota de play antes do setResolvedUrl. Assim
        # esta etapa usa rede em paralelo e não bloqueia a abertura do vídeo.
        paths = subtitles.get_and_download_subtitles(
            job.get('imdb_id'), job.get('media_type'),
            season=job.get('season') or None,
            episode=job.get('episode') or None,
            addon=addon,
            clear_before=False,
            job_id=job_id,
        )
        fetch_ms = int((time.time() - started) * 1000)
        if not paths:
            log_event('Subtitles', 'nao_encontrada', addon=addon,
                      job=job_id[:8], modo='background', tempo_ms=fetch_ms)
            return

        player, state, wait_ms = _wait_for_expected_player(job, xbmc.Monitor())
        if player is None:
            log_event('Subtitles', 'descartada', addon=addon,
                      job=job_id[:8], motivo=state, espera_ms=wait_ms)
            return
        try:
            player.setSubtitles(paths[0])
            log_event('Subtitles', 'anexada', addon=addon,
                      job=job_id[:8], modo='background',
                      busca_ms=fetch_ms, espera_player_ms=wait_ms)
        except Exception as exc:
            log_exception('Subtitles', 'Falha ao anexar legenda ao player', exc,
                          addon=addon, level=getattr(xbmc, 'LOGWARNING', None))
    except Exception as exc:
        try:
            log_exception('Subtitles', 'Worker assíncrono de legenda falhou', exc,
                          addon=addon, level=getattr(xbmc, 'LOGWARNING', None))
        except Exception:
            pass
    finally:
        try:
            subtitles.remove_async_subtitle_job(job_id, addon=addon)
        except Exception:
            pass


if __name__ == '__main__':
    main()
