/*
 * Hermes Node Android
 * Copyright (C) 2026 Stefy Lanza <stefy@nexlab.net>
 * SPDX-License-Identifier: GPL-3.0-or-later
 */
package net.nexlab.hermesnodeandroid

import org.json.JSONArray
import org.json.JSONObject

data class NodeConfig(
    val gatewayUrl: String,
    val token: String,
    val nodeName: String,
    val enableExec: Boolean = false,
    val enableComputerControl: Boolean = true,
    val enableDesktopObserve: Boolean = true,
    val enableAudioControl: Boolean = true,
    val enableCameraControl: Boolean = true,
    val enableBrowserControl: Boolean = false,
    val enableNotificationAccess: Boolean = false,
    val insecureTls: Boolean = true,
    val reconnectIntervalSeconds: Long = 5L,
    val heartbeatIntervalSeconds: Long = 30L,
) {
    fun validationError(): String? = when {
        gatewayUrl.isBlank() -> "Gateway URL is required"
        !(gatewayUrl.startsWith("ws://") || gatewayUrl.startsWith("wss://")) -> "Gateway URL must start with ws:// or wss://"
        token.isBlank() -> "Gateway token is required"
        nodeName.isBlank() -> "Node name is required"
        else -> null
    }
}

data class GatewayCommand(
    val id: String,
    val type: String,
    val action: String?,
    val command: String?,
    val params: JSONObject,
) {
    companion object {
        fun fromJson(raw: String): GatewayCommand {
            val obj = JSONObject(raw)
            return GatewayCommand(
                id = obj.optString("id"),
                type = obj.optString("type"),
                action = obj.optString("action", null),
                command = obj.optString("command", null),
                params = obj.optJSONObject("params") ?: JSONObject(),
            )
        }
    }
}

data class CapabilityResult(
    val success: Boolean,
    val data: JSONObject = JSONObject(),
    val error: String? = null,
) {
    fun toWireResult(resultType: String, id: String, action: String? = null): String {
        val obj = JSONObject()
            .put("type", resultType)
            .put("id", id)
            .put("success", success)
        if (action != null) obj.put("action", action)
        if (error != null) obj.put("error", error)
        for (key in data.keys()) obj.put(key, data.get(key))
        return obj.toString()
    }

    companion object {
        fun unsupported(message: String) = CapabilityResult(false, error = message)
        fun ok(vararg pairs: Pair<String, Any?>): CapabilityResult {
            val obj = JSONObject()
            pairs.forEach { (k, v) -> obj.put(k, v) }
            return CapabilityResult(true, obj)
        }
    }
}

fun jsonArrayOf(items: Iterable<String>): JSONArray {
    val arr = JSONArray()
    items.forEach { arr.put(it) }
    return arr
}
