package com.flashlink.vpn

import android.annotation.SuppressLint
import android.content.Context
import android.os.SystemClock
import org.json.JSONObject
import java.io.File
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock

/**
 * 应用日志记录器 - Kotlin版本
 * 优化点：
 * 1. 优化文件读写操作，使用缓冲区
 * 2. 减少锁持有时间
 * 3. 优化JSON操作
 * 4. 改进异常处理和资源管理
 */
class AppLogger private constructor(context: Context) {
    
    private val context: Context = context.applicationContext
    
    // 全局文件锁，防止多个方法同时读写文件
    private val fileLock = ReentrantLock()
    
    companion object {
        private const val LOG_FOLDER = "boost_logs"
        private const val CURRENT_APP_LOG_FILE = "app.json"
        private const val BUFFER_SIZE = 8192

        @SuppressLint("StaticFieldLeak")
        @Volatile
        private var instance: AppLogger? = null
        
        fun getInstance(context: Context): AppLogger {
            return instance ?: synchronized(this) {
                instance ?: AppLogger(context).also { instance = it }
            }
        }
    }
    
    /**
     * 获取app.json文件路径
     */
    private fun getAppLogFile(): File {
        val logDir = File(context.filesDir, LOG_FOLDER)
        if (!logDir.exists()) {
            logDir.mkdirs()
        }
        return File(logDir, CURRENT_APP_LOG_FILE)
    }
    
    /**
     * 读取app.json文件内容 - 优化版本
     * 使用缓冲区提高读取效率
     */
    private fun readAppJsonFile(): JSONObject {
        val appLogFile = getAppLogFile()
        if (!appLogFile.exists()) {
            throw RuntimeException("app.json file does not exist")
        }
        
        val content = appLogFile.bufferedReader(bufferSize = BUFFER_SIZE).use { it.readText() }
        
        if (content.isEmpty()) {
            throw RuntimeException("app.json file is empty")
        }
        
        return JSONObject(content)
    }
    
    /**
     * 写入app.json文件内容 - 优化版本
     */
    private fun writeAppJsonFile(appData: JSONObject) {
        val appLogFile = getAppLogFile()
        appLogFile.bufferedWriter().use { writer ->
            writer.write(appData.toString(2))
            writer.flush()
        }
    }
    
    /**
     * 安全地更新app.json文件 - 优化版本
     * 减少锁持有时间
     */
    private inline fun safeUpdateAppJson(operationName: String, crossinline update: (JSONObject) -> Unit) {
        fileLock.withLock {
            try {
                val appData = readAppJsonFile()
                
                val sessionInfo = appData.optJSONObject("sessionInfo")
                if (sessionInfo == null) {
                    VLog.w(TAG, "$operationName sessionInfo not found in app.json")
                    return
                }
                
                // 执行具体的更新操作
                try {
                    update(sessionInfo)
                } catch (e: Exception) {
                    VLog.e(TAG, "$operationName Error in update callback: ${e.message}")
                    return
                }
                
                // 保存更新后的文件
                writeAppJsonFile(appData)
                VLog.i(TAG, "$operationName successfully updated app.json")
                
            } catch (e: Exception) {
                VLog.e(TAG, "$operationName Error updating app.json: ${e.message}")
            }
        }
    }
    
    /**
     * 安全地更新JSONObject - 优化版本
     */
    private fun safePut(jsonObject: JSONObject?, key: String, value: Any?, operationName: String) {
        if (jsonObject == null) {
            VLog.e(TAG, "$operationName JSONObject is null, cannot put key: $key")
            return
        }
        
        try {
            jsonObject.put(key, value)
        } catch (e: Exception) {
            VLog.e(TAG, "$operationName Failed to put key '$key' with value '$value': ${e.message}")
        }
    }
    
    /**
     * 更新app.json文件中的boostStopTime、boostDuration
     * 通过 app.json 中的 boostStartTime 和 elapsedRealtime 计算
     * boostStopTime = SystemClock.elapsedRealtime() - elapsedRealtime + boostStartTime
     */
    fun updateAppJsonStopTime() {
        safeUpdateAppJson("updateAppJsonStopTime") { sessionInfo ->
            val boostStartTime = sessionInfo.optLong("boostStartTime", 0)
            val boostSuccessTime = sessionInfo.optLong("boostSuccessTime", 0)
            val savedElapsedRealtime = sessionInfo.optLong("elapsedRealtime", 0)
            
            if (boostStartTime == 0L) {
                throw RuntimeException("boostStartTime not found or invalid in app.json")
            }
            
            // 计算 boostStopTime
            var boostStopTime = if (savedElapsedRealtime != 0L) {
                // 使用保存的 elapsedRealtime 计算精确的停止时间
                SystemClock.elapsedRealtime() - savedElapsedRealtime + boostStartTime
            } else {
                // 降级使用系统时间
                System.currentTimeMillis()
            }
            
            // 计算 boostDuration
            val boostDuration: Long
            if (boostSuccessTime != 0L) {
                if (boostStopTime < boostSuccessTime) {
                    boostStopTime = boostSuccessTime
                }
                boostDuration = (boostStopTime - boostSuccessTime) / 1000
            } else {
                if (boostStopTime < boostStartTime) {
                    boostStopTime = boostStartTime
                }
                boostDuration = (boostStopTime - boostStartTime) / 1000
            }
            
            safePut(sessionInfo, "boostStopTime", boostStopTime, "updateAppJsonStopTime")
            safePut(sessionInfo, "boostDuration", boostDuration, "updateAppJsonStopTime")
        }
    }
    
    /**
     * 更新app.json文件中的success、errorCode、boostSuccessTime
     * 通过 app.json 中的 boostStartTime 和 elapsedRealtime 计算
     * boostSuccessTime = SystemClock.elapsedRealtime() - elapsedRealtime + boostStartTime
     */
    fun updateAppJsonStatusInfo(success: Boolean, errorCode: Long) {
        safeUpdateAppJson("updateAppJsonStatusInfo") { sessionInfo ->
            safePut(sessionInfo, "success", success, "updateAppJsonStatusInfo")
            safePut(sessionInfo, "errorCode", errorCode, "updateAppJsonStatusInfo")
            
            val boostStartTime = sessionInfo.optLong("boostStartTime", 0)
            val savedElapsedRealtime = sessionInfo.optLong("elapsedRealtime", 0)
            
            if (boostStartTime == 0L) {
                throw RuntimeException("boostStartTime not found or invalid in app.json")
            }
            
            // 计算 boostSuccessTime
            var boostSuccessTime = if (savedElapsedRealtime != 0L) {
                // 使用保存的 elapsedRealtime 计算精确的成功时间
                SystemClock.elapsedRealtime() - savedElapsedRealtime + boostStartTime
            } else {
                // 降级使用系统时间
                System.currentTimeMillis()
            }
            
            if (success) {
                // 校验时间合理性：不能早于开始时间，也不能晚于开始时间超过3分钟
                if (boostSuccessTime < boostStartTime || boostSuccessTime - 180000 > boostStartTime) {
                    boostSuccessTime = boostStartTime
                }
                safePut(sessionInfo, "boostSuccessTime", boostSuccessTime, "updateAppJsonStatusInfo")
                safePut(sessionInfo, "boostStopTime", boostSuccessTime, "updateAppJsonStatusInfo")
                safePut(sessionInfo, "boostDuration", 0, "updateAppJsonStatusInfo")
            }
        }
    }
    
    /**
     * 更新app.json文件中的boostDownloadDuration - 优化版本
     */
    fun updateAppJsonDownloadDuration(downloadDuration: Long) {
        safeUpdateAppJson("updateAppJsonDownloadDuration") { sessionInfo ->
            safePut(sessionInfo, "boostDownloadDuration", downloadDuration, "updateAppJsonDownloadDuration")
        }
    }
    
    /**
     * 更新app.json文件中的errorCode - 优化版本
     */
    fun updateAppJsonCode(code: Int) {
        safeUpdateAppJson("updateAppJsonCode") { sessionInfo ->
            safePut(sessionInfo, "errorCode", code, "updateAppJsonCode")
        }
    }
}

private const val TAG = "AppLogger"
