package com.rosetta.messenger.utils import android.util.Log import com.rosetta.messenger.network.ProtocolManager /** * Утилита для логирования сообщений * Безопасна для release сборки - логи не выводятся в production * * Логи отображаются: * 1. В Logcat (всегда в debug) * 2. В Debug Logs внутри чата (через ProtocolManager.debugLogs) */ object MessageLogger { private const val TAG = "RosettaMsg" // Включить/выключить логирование (только в DEBUG) private val isEnabled: Boolean = android.os.Build.TYPE != "user" /** * Добавить лог в UI (Debug Logs в чате) */ private fun addToUI(message: String) { ProtocolManager.addLog(message) } /** * Логирование отправки сообщения */ fun logSendStart( messageId: String, toPublicKey: String, textLength: Int, attachmentsCount: Int, isSavedMessages: Boolean, replyToMessageId: String? ) { if (!isEnabled) return val shortId = messageId.take(8) val shortKey = toPublicKey.take(12) val replyStr = replyToMessageId?.take(8) ?: "-" val msg = "📤 SEND | id:$shortId to:$shortKey len:$textLength att:$attachmentsCount saved:$isSavedMessages reply:$replyStr" Log.d(TAG, msg) addToUI(msg) } /** * Логирование успешного шифрования */ fun logEncryptionSuccess( messageId: String, encryptedContentLength: Int, encryptedKeyLength: Int ) { if (!isEnabled) return val shortId = messageId.take(8) val msg = "🔐 ENCRYPT | id:$shortId content:${encryptedContentLength}b key:${encryptedKeyLength}b" Log.d(TAG, msg) addToUI(msg) } /** * Логирование сохранения в БД */ fun logDbSave( messageId: String, dialogKey: String, isNew: Boolean ) { if (!isEnabled) return val shortId = messageId.take(8) val shortDialog = dialogKey.take(12) val msg = "💾 DB | id:$shortId dialog:$shortDialog new:$isNew" Log.d(TAG, msg) addToUI(msg) } /** * Логирование отправки пакета на сервер */ fun logPacketSend( messageId: String, toPublicKey: String, timestamp: Long ) { if (!isEnabled) return val shortId = messageId.take(8) val shortKey = toPublicKey.take(12) val msg = "📡 PACKET→ | id:$shortId to:$shortKey ts:$timestamp" Log.d(TAG, msg) addToUI(msg) } /** * Логирование успешной отправки */ fun logSendSuccess(messageId: String, duration: Long) { if (!isEnabled) return val shortId = messageId.take(8) val msg = "✅ SENT | id:$shortId time:${duration}ms" Log.d(TAG, msg) addToUI(msg) } /** * Логирование ошибки отправки */ fun logSendError(messageId: String, error: Throwable) { if (!isEnabled) return val shortId = messageId.take(8) val errMsg = error.message?.take(50) ?: "unknown" val msg = "❌ SEND ERR | id:$shortId err:$errMsg" Log.e(TAG, msg, error) addToUI(msg) } /** * Логирование входящего сообщения */ fun logReceiveStart( messageId: String, fromPublicKey: String, toPublicKey: String, contentLength: Int, attachmentsCount: Int, timestamp: Long ) { if (!isEnabled) return val shortId = messageId.take(8) val shortFrom = fromPublicKey.take(12) val shortTo = toPublicKey.take(12) val msg = "📥 RECV | id:$shortId from:$shortFrom to:$shortTo len:${contentLength}b att:$attachmentsCount ts:$timestamp" Log.d(TAG, msg) addToUI(msg) } /** * Логирование проверки на дубликат */ fun logDuplicateCheck(messageId: String, isDuplicate: Boolean) { if (!isEnabled) return val shortId = messageId.take(8) val status = if (isDuplicate) "⚠️DUP" else "✓NEW" val msg = "🔍 CHECK | id:$shortId $status" Log.d(TAG, msg) addToUI(msg) } /** * Логирование блокировки отправителя */ fun logBlockedSender(fromPublicKey: String) { if (!isEnabled) return val shortKey = fromPublicKey.take(12) val msg = "🚫 BLOCKED | from:$shortKey" Log.d(TAG, msg) addToUI(msg) } /** * Логирование успешной расшифровки */ fun logDecryptionSuccess( messageId: String, plainTextLength: Int, attachmentsCount: Int ) { if (!isEnabled) return val shortId = messageId.take(8) val msg = "🔓 DECRYPT | id:$shortId text:${plainTextLength}c att:$attachmentsCount" Log.d(TAG, msg) addToUI(msg) } /** * Логирование ошибки расшифровки */ fun logDecryptionError(messageId: String, error: Throwable) { if (!isEnabled) return val shortId = messageId.take(8) val errMsg = error.message?.take(50) ?: "unknown" val msg = "❌ DECRYPT ERR | id:$shortId err:$errMsg" Log.e(TAG, msg, error) addToUI(msg) } /** * Логирование успешного получения */ fun logReceiveSuccess(messageId: String, duration: Long) { if (!isEnabled) return val shortId = messageId.take(8) val msg = "✅ RECEIVED | id:$shortId time:${duration}ms" Log.d(TAG, msg) addToUI(msg) } /** * Логирование обновления статуса доставки */ fun logDeliveryStatus( messageId: String, toPublicKey: String, status: String ) { if (!isEnabled) return val shortId = messageId.take(8) val shortKey = toPublicKey.take(12) val msg = "📬 DELIVERY | id:$shortId to:$shortKey status:$status" Log.d(TAG, msg) addToUI(msg) } /** * Логирование прочтения сообщений */ fun logReadStatus( fromPublicKey: String, messagesCount: Int ) { if (!isEnabled) return val shortKey = fromPublicKey.take(12) val msg = "👁 READ | from:$shortKey count:$messagesCount" Log.d(TAG, msg) addToUI(msg) } /** * Логирование обновления диалога */ fun logDialogUpdate( dialogKey: String, lastMessage: String?, unreadCount: Int ) { if (!isEnabled) return val shortDialog = dialogKey.take(12) val shortMsg = lastMessage?.take(20) ?: "-" val msg = "📋 DIALOG | key:$shortDialog last:\"$shortMsg\" unread:$unreadCount" Log.d(TAG, msg) addToUI(msg) } /** * Логирование обновления кэша */ fun logCacheUpdate(dialogKey: String, totalMessages: Int) { if (!isEnabled) return val shortDialog = dialogKey.take(12) val msg = "🗃 CACHE | dialog:$shortDialog total:$totalMessages" Log.d(TAG, msg) addToUI(msg) } /** * Общий debug лог */ fun debug(message: String) { if (!isEnabled) return Log.d(TAG, message) addToUI(message) } /** * Общий error лог */ fun error(message: String, error: Throwable? = null) { if (!isEnabled) return if (error != null) { Log.e(TAG, message, error) } else { Log.e(TAG, message) } addToUI("❌ $message") } }