package com.inou.clawdnode.security

import android.content.Context
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.ConcurrentLinkedQueue

/**
 * Local audit log for all ClawdNode actions.
 * Security-first: every action is logged with timestamp.
 */
class AuditLog(private val context: Context) {
    
    private val gson: Gson = GsonBuilder().setPrettyPrinting().create()
    private val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US).apply {
        timeZone = TimeZone.getTimeZone("UTC")
    }
    
    private val pendingEntries = ConcurrentLinkedQueue<AuditEntry>()
    private val logFile: File
        get() {
            val dir = File(context.filesDir, "audit")
            if (!dir.exists()) dir.mkdirs()
            val today = SimpleDateFormat("yyyy-MM-dd", Locale.US).format(Date())
            return File(dir, "audit-$today.jsonl")
        }
    
    fun log(action: String, details: String, metadata: Map<String, Any>? = null) {
        val entry = AuditEntry(
            timestamp = dateFormat.format(Date()),
            action = action,
            details = details,
            metadata = metadata
        )
        
        pendingEntries.add(entry)
        flushToFile()
    }
    
    fun logCall(action: String, number: String?, contact: String?, outcome: String?) {
        log(
            action = action,
            details = "Call ${action.lowercase()}",
            metadata = mapOf(
                "number" to (number ?: "unknown"),
                "contact" to (contact ?: "unknown"),
                "outcome" to (outcome ?: "pending")
            ).filterValues { it != "unknown" && it != "pending" }
        )
    }
    
    fun logNotification(action: String, app: String, title: String?) {
        log(
            action = action,
            details = "Notification from $app",
            metadata = mapOf(
                "app" to app,
                "title" to (title ?: "")
            ).filterValues { it.isNotEmpty() }
        )
    }
    
    fun logCommand(command: String, source: String, success: Boolean) {
        log(
            action = "COMMAND_${if (success) "OK" else "FAIL"}",
            details = "Executed: $command",
            metadata = mapOf(
                "command" to command,
                "source" to source,
                "success" to success
            )
        )
    }
    
    private fun flushToFile() {
        try {
            logFile.appendText(
                pendingEntries.map { gson.toJson(it) }.joinToString("\n") + "\n"
            )
            pendingEntries.clear()
        } catch (e: Exception) {
            // Don't crash on log failure, but keep entries for retry
        }
    }
    
    fun getRecentEntries(limit: Int = 100): List<AuditEntry> {
        return try {
            logFile.readLines()
                .takeLast(limit)
                .mapNotNull { 
                    try { gson.fromJson(it, AuditEntry::class.java) } 
                    catch (e: Exception) { null }
                }
        } catch (e: Exception) {
            emptyList()
        }
    }
    
    data class AuditEntry(
        val timestamp: String,
        val action: String,
        val details: String,
        val metadata: Map<String, Any>? = null
    )
}
