package com.flashlink.vpn

import android.content.Context
import android.util.Log
import java.io.File
import java.io.FileWriter
import java.io.PrintWriter
import java.io.RandomAccessFile
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.concurrent.Executors
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock

/**
 * 文件日志工具类
 * 将日志同时输出到 logcat 和文件，确保日志不丢失
 */
object VLog {
    private var logFile: File? = null
    private var writer: PrintWriter? = null
    private val lock = ReentrantLock()
    private val executor = Executors.newSingleThreadExecutor()
    private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault())
    
    private const val MAX_LOG_SIZE = 10 * 1024 * 1024 // 10MB
    private const val MAX_LOG_FILES = 1 // 每种类型就保留一个日志文件
    
    // 当前日志类型，用于同步写入到 PersistentLog
    private var currentLogType: PersistentLog.LogType? = null
    
    /**
     * 初始化日志系统
     */
    fun init(context: Context, name: String = "service") {
        // 同时初始化 PersistentLog
        currentLogType = when (name.lowercase()) {
            "client" -> {
                PersistentLog.initClient(context)
                PersistentLog.LogType.CLIENT
            }
            else -> {
                PersistentLog.initService(context)
                PersistentLog.LogType.SERVICE
            }
        }
        
        executor.execute {
            try {
                val logDir = File(context.filesDir, "logs")
                if (!logDir.exists()) {
                    logDir.mkdirs()
                }
                
                // 清理旧日志文件
                cleanOldLogs(logDir, name)
                
                // 创建新的日志文件
                val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
                logFile = File(logDir, "${name}_$timestamp.log")
                writer = PrintWriter(FileWriter(logFile, true), true)
                
                i("FileLogger", "日志系统初始化成功: ${logFile?.absolutePath}")
            } catch (e: Exception) {
                Log.e("FileLogger", "初始化日志系统失败", e)
            }
        }
    }
    
    /**
     * 清理旧的日志文件，只保留最近的几个
     */
    private fun cleanOldLogs(logDir: File, name: String) {
        try {
            val logFiles = logDir.listFiles { file ->
                file.name.startsWith("${name}_") && file.name.endsWith(".log")
            }?.sortedByDescending { it.lastModified() } ?: return
            
            // 删除超出数量限制的旧文件
            if (logFiles.size >= MAX_LOG_FILES) {
                logFiles.drop(MAX_LOG_FILES - 1).forEach { file ->
                    file.delete()
                    Log.i("FileLogger", "删除旧日志文件: ${file.name}")
                }
            }
        } catch (e: Exception) {
            Log.e("FileLogger", "清理旧日志失败", e)
        }
    }
    
    /**
     * 检查并轮转日志文件
     */
    private fun checkAndRotateLog(context: Context) {
        try {
            val currentFile = logFile ?: return
            if (currentFile.length() > MAX_LOG_SIZE) {
                writer?.close()
                init(context)
            }
        } catch (e: Exception) {
            Log.e("FileLogger", "轮转日志文件失败", e)
        }
    }
    
    /**
     * 写入日志
     */
    private fun writeLog(level: String, tag: String, message: String, throwable: Throwable? = null) {
        // 同时写入到 PersistentLog（不输出到 logcat，因为调用方已经输出）
        currentLogType?.let { logType ->
            PersistentLog.writeLogOnly(logType, level, tag, message, throwable)
        }
        
        executor.execute {
            lock.withLock {
                try {
                    val timestamp = dateFormat.format(Date())
                    val logMessage = "[$timestamp] [$level] [$tag] $message"
                    
                    writer?.println(logMessage)
                    throwable?.let {
                        writer?.println(it.stackTraceToString())
                    }
                    writer?.flush()
                } catch (e: Exception) {
                    Log.e("FileLogger", "写入日志失败", e)
                }
            }
        }
    }
    
    /**
     * Info 级别日志
     */
    fun i(tag: String, message: String) {
        Log.i(tag, message)
        writeLog("INFO", tag, message)
    }
    
    /**
     * Debug 级别日志
     */
    fun d(tag: String, message: String) {
        Log.d(tag, message)
        writeLog("DEBUG", tag, message)
    }
    
    /**
     * Warning 级别日志
     */
    fun w(tag: String, message: String, throwable: Throwable? = null) {
        Log.w(tag, message, throwable)
        writeLog("WARN", tag, message, throwable)
    }
    
    /**
     * Error 级别日志
     */
    fun e(tag: String, message: String, throwable: Throwable? = null) {
        Log.e(tag, message, throwable)
        writeLog("ERROR", tag, message, throwable)
    }
    
    /**
     * 获取当前日志文件路径
     */
    fun getLogFilePath(): String? {
        return logFile?.absolutePath
    }
    
    /**
     * 关闭日志系统
     */
    fun close() {
        executor.execute {
            lock.withLock {
                try {
                    writer?.close()
                    writer = null
                } catch (e: Exception) {
                    Log.e("FileLogger", "关闭日志系统失败", e)
                }
            }
        }
    }
}

/**
 * 持久化日志管理器
 * 支持两种独立的日志类型：
 * - Client: 客户端日志，最大10MB
 * - Service: 服务日志，最大30MB
 * 
 * 特点：
 * - 使用固定文件名，重启后继续追加，不会重置
 * - 超过大小限制时自动截断旧日志，保留最近内容
 */
object PersistentLog {
    
    /**
     * 日志类型枚举
     */
    enum class LogType(val fileName: String, val maxSize: Long) {
        CLIENT("client.log", 10 * 1024 * 1024L),   // 10MB
        SERVICE("service.log", 30 * 1024 * 1024L)  // 30MB
    }
    
    private data class LogWriter(
        var file: File,
        var writer: PrintWriter?,
        val maxSize: Long
    )
    
    private val logWriters = mutableMapOf<LogType, LogWriter>()
    private val lock = ReentrantLock()
    private val executor = Executors.newSingleThreadExecutor()
    private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault())
    private var logDir: File? = null
    
    // 当文件超过最大大小时，保留最近的这个比例的内容
    private const val TRUNCATE_KEEP_RATIO = 0.7
    
    /**
     * 初始化客户端日志系统
     */
    fun initClient(context: Context) {
        init(context, LogType.CLIENT)
    }
    
    /**
     * 初始化Service日志系统
     */
    fun initService(context: Context) {
        init(context, LogType.SERVICE)
    }
    
    /**
     * 初始化指定类型的日志系统
     */
    private fun init(context: Context, logType: LogType) {
        executor.execute {
            lock.withLock {
                try {
                    val dir = File(context.filesDir, "logs")
                    if (!dir.exists()) {
                        dir.mkdirs()
                    }
                    logDir = dir
                    
                    // 使用固定文件名，支持追加
                    val logFile = File(dir, logType.fileName)
                    
                    // 检查文件大小，如果超过限制则截断
                    if (logFile.exists() && logFile.length() > logType.maxSize) {
                        truncateLogFile(logFile, logType.maxSize)
                    }
                    
                    // 创建或追加到日志文件
                    val writer = PrintWriter(FileWriter(logFile, true), true)
                    logWriters[logType] = LogWriter(logFile, writer, logType.maxSize)
                    
                    val timestamp = dateFormat.format(Date())
                    writer.println("\n[$timestamp] [INFO] [PersistentLog] ========== 日志系统启动 (${logType.name}) ==========")
                    writer.flush()
                    
                    Log.i("PersistentLog", "${logType.name} 日志系统初始化成功: ${logFile.absolutePath}, 当前大小: ${logFile.length() / 1024}KB")
                } catch (e: Exception) {
                    Log.e("PersistentLog", "初始化 ${logType.name} 日志系统失败", e)
                }
            }
        }
    }
    
    /**
     * 截断日志文件，保留最近的内容
     */
    private fun truncateLogFile(file: File, maxSize: Long) {
        try {
            val keepSize = (maxSize * TRUNCATE_KEEP_RATIO).toLong()
            val fileSize = file.length()
            
            if (fileSize <= maxSize) return
            
            Log.i("PersistentLog", "日志文件超过限制，开始截断: ${file.name}, 当前大小: ${fileSize / 1024 / 1024}MB")
            
            // 读取文件末尾的内容
            RandomAccessFile(file, "r").use { raf ->
                val skipBytes = fileSize - keepSize
                raf.seek(skipBytes)
                
                // 跳过可能的不完整行
                raf.readLine()
                
                // 读取剩余内容
                val remainingBytes = ByteArray((fileSize - raf.filePointer).toInt())
                raf.readFully(remainingBytes)
                
                // 写入新文件
                file.writeBytes(remainingBytes)
            }
            
            // 在文件开头添加截断标记
            val tempFile = File(file.parent, "${file.name}.tmp")
            val timestamp = dateFormat.format(Date())
            tempFile.writeText("[$timestamp] [INFO] [PersistentLog] ========== 日志已截断，保留最近内容 ==========\n")
            tempFile.appendBytes(file.readBytes())
            tempFile.renameTo(file)
            
            Log.i("PersistentLog", "日志文件截断完成: ${file.name}, 新大小: ${file.length() / 1024 / 1024}MB")
        } catch (e: Exception) {
            Log.e("PersistentLog", "截断日志文件失败", e)
            // 如果截断失败，尝试直接清空文件
            try {
                file.writeText("")
                Log.w("PersistentLog", "截断失败，已清空日志文件: ${file.name}")
            } catch (e2: Exception) {
                Log.e("PersistentLog", "清空日志文件也失败", e2)
            }
        }
    }
    
    /**
     * 检查并轮转日志文件
     */
    private fun checkAndRotateIfNeeded(logType: LogType) {
        val logWriter = logWriters[logType] ?: return
        try {
            if (logWriter.file.length() > logWriter.maxSize) {
                logWriter.writer?.close()
                truncateLogFile(logWriter.file, logWriter.maxSize)
                logWriter.writer = PrintWriter(FileWriter(logWriter.file, true), true)
            }
        } catch (e: Exception) {
            Log.e("PersistentLog", "轮转日志文件失败", e)
        }
    }
    
    /**
     * 写入日志到指定类型（内部使用，同时输出到 logcat）
     */
    private fun writeLog(logType: LogType, level: String, tag: String, message: String, throwable: Throwable? = null) {
        writeLogInternal(logType, level, tag, message, throwable)
    }
    
    /**
     * 只写入日志到文件，不输出到 logcat（供 VLog 调用，避免重复输出）
     */
    fun writeLogOnly(logType: LogType, level: String, tag: String, message: String, throwable: Throwable? = null) {
        writeLogInternal(logType, level, tag, message, throwable)
    }
    
    /**
     * 内部写入日志方法
     */
    private fun writeLogInternal(logType: LogType, level: String, tag: String, message: String, throwable: Throwable? = null) {
        executor.execute {
            lock.withLock {
                try {
                    val logWriter = logWriters[logType] ?: return@withLock
                    
                    val timestamp = dateFormat.format(Date())
                    val logMessage = "[$timestamp] [$level] [$tag] $message"
                    
                    logWriter.writer?.println(logMessage)
                    throwable?.let {
                        logWriter.writer?.println(it.stackTraceToString())
                    }
                    logWriter.writer?.flush()
                    
                    // 检查是否需要轮转
                    checkAndRotateIfNeeded(logType)
                } catch (e: Exception) {
                    Log.e("PersistentLog", "写入日志失败", e)
                }
            }
        }
    }
    
    // ==================== 客户端日志方法 ====================
    
    /**
     * 客户端 Info 级别日志
     */
    fun ci(tag: String, message: String) {
        Log.i(tag, message)
        writeLog(LogType.CLIENT, "INFO", tag, message)
    }
    
    /**
     * 客户端 Debug 级别日志
     */
    fun cd(tag: String, message: String) {
        Log.d(tag, message)
        writeLog(LogType.CLIENT, "DEBUG", tag, message)
    }
    
    /**
     * 客户端 Warning 级别日志
     */
    fun cw(tag: String, message: String, throwable: Throwable? = null) {
        Log.w(tag, message, throwable)
        writeLog(LogType.CLIENT, "WARN", tag, message, throwable)
    }
    
    /**
     * 客户端 Error 级别日志
     */
    fun ce(tag: String, message: String, throwable: Throwable? = null) {
        Log.e(tag, message, throwable)
        writeLog(LogType.CLIENT, "ERROR", tag, message, throwable)
    }
    
    // ==================== Service日志方法 ====================
    
    /**
     * Service Info 级别日志
     */
    fun si(tag: String, message: String) {
        Log.i(tag, message)
        writeLog(LogType.SERVICE, "INFO", tag, message)
    }
    
    /**
     * Service Debug 级别日志
     */
    fun sd(tag: String, message: String) {
        Log.d(tag, message)
        writeLog(LogType.SERVICE, "DEBUG", tag, message)
    }
    
    /**
     * Service Warning 级别日志
     */
    fun sw(tag: String, message: String, throwable: Throwable? = null) {
        Log.w(tag, message, throwable)
        writeLog(LogType.SERVICE, "WARN", tag, message, throwable)
    }
    
    /**
     * Service Error 级别日志
     */
    fun se(tag: String, message: String, throwable: Throwable? = null) {
        Log.e(tag, message, throwable)
        writeLog(LogType.SERVICE, "ERROR", tag, message, throwable)
    }
    
    // ==================== 工具方法 ====================
    
    /**
     * 获取客户端日志文件路径
     */
    fun getClientLogFilePath(): String? {
        return logWriters[LogType.CLIENT]?.file?.absolutePath
    }
    
    /**
     * 获取Service日志文件路径
     */
    fun getServiceLogFilePath(): String? {
        return logWriters[LogType.SERVICE]?.file?.absolutePath
    }
    
    /**
     * 获取日志目录
     */
    fun getLogDir(): File? {
        return logDir
    }
    
    /**
     * 关闭客户端日志系统
     */
    fun closeClient() {
        close(LogType.CLIENT)
    }
    
    /**
     * 关闭Service日志系统
     */
    fun closeService() {
        close(LogType.SERVICE)
    }
    
    /**
     * 关闭指定类型的日志系统
     */
    private fun close(logType: LogType) {
        executor.execute {
            lock.withLock {
                try {
                    logWriters[logType]?.writer?.close()
                    logWriters.remove(logType)
                } catch (e: Exception) {
                    Log.e("PersistentLog", "关闭 ${logType.name} 日志系统失败", e)
                }
            }
        }
    }
    
    /**
     * 关闭所有日志系统
     */
    fun closeAll() {
        executor.execute {
            lock.withLock {
                try {
                    logWriters.values.forEach { it.writer?.close() }
                    logWriters.clear()
                } catch (e: Exception) {
                    Log.e("PersistentLog", "关闭日志系统失败", e)
                }
            }
        }
    }
}

