# -*- coding: utf-8 -*-
# plugin.video.alkoflix
# resources/lib/modules/log_sanitizer.py

import re

URL_MASK = '[URL MASQUÉ]'
MAGNET_MASK = '[MAGNET MASQUÉ]'
HASH_MASK = '[HASH MASQUÉ]'
TOKEN_MASK = '[TOKEN MASQUÉ]'
ID_MASK = '[ID MASQUÉ]'
FILE_MASK = '[FICHIER MASQUÉ]'

SENSITIVE_KEYS = (
	'api_key', 'apikey', 'x-api-key', 'private.tr4ker.api_key', 'key', 'token', 'auth', 'authorization',
	'password', 'passwd', 'pass', 'secret', 'client_secret', 'access_token', 'refresh_token', 'session_id',
	'username', 'user', 'login', 'm3u_user', 'm3u_username', 'm3u_password', 'xtream_user', 'xtream_username', 'xtream_password',
	'alldebrid_key', 'realdebrid_key', 'real_debrid_key', 'torbox_key', 'debrid_key',
	'tr_yg_open', 'tr_yg_key', 'tr_c411_apikey', 'tr_torr9_passkey', 'tr_gemini_apikey', 'tr_nostradamus_apikey', 'tr_tr4ker_apikey'
)

SENSITIVE_KEYS_PATTERN = '|'.join([re.escape(key) for key in SENSITIVE_KEYS])


def mask_sensitive_value(value):
	value = str(value or '')
	if not value: return ''
	if len(value) <= 6: return value[:2] + '***'
	return value[:3] + '***' + value[-3:]


def _mask_iptv_path_credentials(match):
	return '%s***/***%s' % (match.group(1), match.group(4))


def _mask_url_basic_auth(match):
	return '%s***:***@' % match.group(1)


def _mask_stream_url(match):
	return '%s%s' % (match.group(1), URL_MASK)


def _mask_debrid_numeric_id(match):
	return '%s%s' % (match.group(1), ID_MASK)


def sanitize_log_text(text, mask_paste_ids=False):
	# Masque les valeurs sensibles avant écriture dans le journal Kodi, affichage ou envoi vers alkoPastes.
	# Le but est de garder les lignes utiles au diagnostic sans exposer URLs, magnets, hashes, clés/API,
	# codes paste, identifiants débrideurs ou noms de fichiers/releases.
	text = str(text or '')
	if not text: return text
	text = text.replace('[URL IPTV masquée]', URL_MASK)
	try:
		# Lignes de lecture/PVR : l'URL complète peut exposer serveur, chemin, user/pass ou tokens selon le format.
		text = re.sub(r"(?i)((?:Live Stream URL:|Stream URL:|InputStream:|OpenFile:|Opening stream:|VideoPlayer::OpenFile:)[^\n\r]*?)https?://[^\s'\"<>]+", _mask_stream_url, text)
		# Champs url= ou resolved_url= dans les logs applicatifs.
		text = re.sub(r"(?i)(\b(?:url|resolved_url|stream_url|play_url|source_url|download_url)\s*=\s*)https?://[^\s'\"<>|]+", r"\1%s" % URL_MASK, text)
		# Domaines/chemins connus pouvant contenir des paramètres de lecture ou de source.
		text = re.sub(r"(?i)https?://[^\s'\"<>]*(?:baguettio|alldebrid|real-debrid|realdebrid|torbox|debrid\.it|comet|aio)[^\s'\"<>]*", URL_MASK, text)
		# Magnets et hashes torrent.
		text = re.sub(r"(?i)magnet:\?xt=urn:btih:[^\s'\"<>|]+", MAGNET_MASK, text)
		text = re.sub(r"(?i)(\bhash\s*=\s*)[a-f0-9]{32,64}\b", r"\1%s" % HASH_MASK, text)
		text = re.sub(r"(?i)(\bbtih:)[a-f0-9]{32,64}\b", r"\1%s" % HASH_MASK, text)
		text = re.sub(r"(?i)\b[a-f0-9]{40}\b", HASH_MASK, text)
		text = re.sub(r"(?i)\b[a-f0-9]{64,}\b", TOKEN_MASK, text)
		# IDs numériques de magnets/torrents dans les lignes débrideur.
		text = re.sub(r"(?i)((?:AllDebrid|RealDebrid|Real-Debrid|TorBox)[^\n\r]*?\b(?:id|magnet_id|torrent_id)\s*=\s*)\d{4,}\b", _mask_debrid_numeric_id, text)
		text = re.sub(r"(?i)((?:Magnet créé|Pack analysé|Magnet supprimé|Upload magnet|Analyse du pack)[^\n\r]*?\bid\s*=\s*)\d{4,}\b", _mask_debrid_numeric_id, text)
		# Noms de fichiers/releases : utiles localement, mais trop bavards pour un log partageable.
		text = re.sub(r"(?i)(\b(?:fichier|filename|file_name|release|release_title|torrent_name|name)\s*=\s*)([^|\n\r]+)(?=\s*(?:\||\n|\r|$))", r"\1%s" % FILE_MASK, text)
		# Formats type dict/json : {'api_key': 'xxx'}, "token": "xxx"
		text = re.sub(r"(?i)(['\"]?(?:%s)['\"]?\s*[:=]\s*['\"])([^'\"\s,}&]+)(['\"]?)" % SENSITIVE_KEYS_PATTERN, r"\1***\3", text)
		# Paramètres d'URL : ?username=xxx&password=yyy&token=zzz
		text = re.sub(r"(?i)([?&](?:%s)=)([^&\s'\"<>]+)" % SENSITIVE_KEYS_PATTERN, r"\1***", text)
		# URLs avec authentification HTTP : http://user:pass@host/...
		text = re.sub(r"(?i)(https?://)([^:/@\s'\"<>]+):([^/@\s'\"<>]+)@", _mask_url_basic_auth, text)
		# URLs Xtream/IPTV classiques : /live/user/pass/..., /movie/user/pass/..., /series/user/pass/...
		text = re.sub(r"(?i)(https?://[^/\s'\"<>]+/(?:live|movie|series)/)([^/\s'\"<>]+)/([^/\s'\"<>]+)(/)", _mask_iptv_path_credentials, text)
		# Variante M3U fréquente sans préfixe live/movie/series : http://host:port/user/pass/123.ts
		text = re.sub(r"(?i)(https?://[^/\s'\"<>]+/(?!live/|movie/|series/))([^/\s'\"<>]+)/([^/\s'\"<>]+)(/[^\s'\"<>]*(?:\.ts|\.m3u8|\.mp4|\.mkv|\.avi|\.mov)(?:[?&][^\s'\"<>]*)?)", _mask_iptv_path_credentials, text)
		# PVR IPTV Simple logue parfois des URLs Xtream sans extension : http://host:port/user/pass/123
		text = re.sub(r"(?i)((?:Live Stream URL:|Stream URL:|InputStream:|OpenFile:|Opening stream:|VideoPlayer::OpenFile:)[^\n\r]*?https?://[^/\s'\"<>]+/)([^/\s'\"<>]+)/([^/\s'\"<>]+)(/[^\s'\"<>]+)", _mask_iptv_path_credentials, text)
		# En-têtes Authorization: Bearer xxx
		text = re.sub(r"(?i)(Bearer\s+)[A-Za-z0-9._\-]+", r"\1***", text)
		# URLs alkoPastes directes éventuelles : /raw/code ou /code
		text = re.sub(r"(?i)(paste\.lesalkodiques\.(?:com|info)/(?:raw/)?)(([A-Za-z0-9_-]{6,}))", lambda m: m.group(1) + mask_sensitive_value(m.group(2)), text)
		if mask_paste_ids:
			# Dans les logs alkoPastes, les champs id/code/p_code/slug correspondent à des codes paste privés.
			text = re.sub(r"(?i)(['\"]id['\"]\s*:\s*['\"])([^'\"]+)(['\"])", lambda m: m.group(1) + mask_sensitive_value(m.group(2)) + m.group(3), text)
			text = re.sub(r"(?i)(['\"](?:code|p_code|slug)['\"]\s*:\s*['\"])([^'\"]+)(['\"])", lambda m: m.group(1) + mask_sensitive_value(m.group(2)) + m.group(3), text)
			text = re.sub(r"(?i)((?:^|[|,\s])(?:code|cached|backup|single|old|new|target)=)([A-Za-z0-9_-]{6,})", lambda m: m.group(1) + mask_sensitive_value(m.group(2)), text)
	except Exception:
		pass
	return text
