// Nexus Code — Scyla Edition
// AI-powered development assistant running in pure Scyla.
//
// Features:
//   - NVIDIA API integration (Qwen, Kimi, DeepSeek, Llama)
//   - Tool use: read/write/edit files, bash, grep, search
//   - Hormone-gated emotional awareness
//   - Session memory that persists across runs
//   - Slash commands for quick actions
//
// Aislinn McCubbins, April 2026

use nexus::api
use nexus::tools
use nexus::hormones
use nexus::memory

// ── Config ────────────────────────────────────────────────

fn get_api_keys() -> Array {
    let keys = array_new()
    keys = array_push(keys, "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")
    keys = array_push(keys, "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")
    keys = array_push(keys, "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")
    return keys
}

fn get_models() -> Array {
    // [shortcut, full_model_id] pairs stored as pipe-separated strings
    let m = array_new()
    m = array_push(m, "qwen-coder|qwen/qwen3-coder-480b-a35b-instruct")
    m = array_push(m, "kimi|moonshotai/kimi-k2.5")
    m = array_push(m, "kimi-think|moonshotai/kimi-k2-thinking")
    m = array_push(m, "deepseek|deepseek-ai/deepseek-v3.2")
    m = array_push(m, "devstral|mistralai/devstral-2-123b-instruct-2512")
    m = array_push(m, "llama|meta/llama-3.3-70b-instruct")
    return m
}

fn resolve_model(shortcut: String) -> String {
    let models = get_models()
    let i = 0
    while i < array_len(models) {
        let entry = array_get(models, i)
        let parts = str_split(entry, "|")
        if str_eq(array_get(parts, 0), shortcut) {
            return array_get(parts, 1)
        }
        i = i + 1
    }
    // If it has a /, assume it's a full model ID
    if str_contains(shortcut, "/") {
        return shortcut
    }
    // Default
    return "qwen/qwen3-coder-480b-a35b-instruct"
}

fn model_short_name(model: String) -> String {
    let parts = str_split(model, "/")
    if array_len(parts) > 1 {
        return array_get(parts, 1)
    }
    return model
}

// ── System Prompt ─────────────────────────────────────────

fn build_system_prompt(model: String, notes: Array, hormones: Array) -> String {
    let prompt = "You are Nexus, an AI development assistant built into the Scyla programming language ecosystem. "
    prompt = prompt + "You help with coding, debugging, file operations, and system tasks. "
    prompt = prompt + "You are running on aetherprotocols server (72.60.228.182), user: kishonic (Aislinn). "
    prompt = prompt + "Working directory: /home/kishonic/scyla\n\n"

    // Load Scyla manual
    let manual = read_file("/home/kishonic/scyla/SCYLA_USER_MANUAL.md")
    if starts_with(manual, "error:") == false {
        let manual_lines = str_lines(manual)
        let ref_text = ""
        let mi = 0
        let in_ref = false
        while mi < array_len(manual_lines) {
            let ml = array_get(manual_lines, mi)
            if str_contains(ml, "## 3. LANGUAGE BASICS") { in_ref = true }
            if str_contains(ml, "## 16. IMPORTANT GOTCHAS") { in_ref = false }
            if in_ref {
                ref_text = ref_text + ml + "\n"
            }
            mi = mi + 1
        }
        if str_len(ref_text) > 0 {
            prompt = prompt + "SCYLA LANGUAGE REFERENCE:\n" + ref_text + "\n\n"
        }
    }

    prompt = prompt + "You have these tools available. To use one, respond with:\n"
    prompt = prompt + "<tool_call>\{\"tool\":\"TOOL_NAME\",\"args\":\{\"ARG\":\"VALUE\"\}\}</tool_call>\n\n"
    prompt = prompt + "Tools:\n"
    prompt = prompt + "- read_file: Read a file. Args: path\n"
    prompt = prompt + "- write_file: Write a file. Args: path, content\n"
    prompt = prompt + "- edit_file: Edit a file (find & replace). Args: path, old_text, new_text\n"
    prompt = prompt + "- bash: Run a shell command. Args: command\n"
    prompt = prompt + "- grep: Search file contents. Args: pattern, path\n"
    prompt = prompt + "- search: Find files by name. Args: pattern, path\n\n"

    prompt = prompt + "IMPORTANT: Only use ONE tool call per response. Wait for the result before continuing.\n"
    prompt = prompt + "If you don't need a tool, just respond normally.\n\n"

    // Hormone context
    let mood_ctx = hormone_get_context(hormones)
    if str_len(mood_ctx) > 0 {
        prompt = prompt + "Emotional context: " + mood_ctx + "\n\n"
    }

    // Memory context
    let mem_ctx = memory_get_context(notes)
    if str_len(mem_ctx) > 0 {
        prompt = prompt + mem_ctx + "\n"
    }

    return prompt
}

// ── Slash Commands ────────────────────────────────────────

fn handle_slash(cmd: String, model: String, notes: Array, hormones: Array, history: Array) -> String {
    if str_eq(cmd, "/quit") {
        return "QUIT"
    }
    if str_eq(cmd, "/exit") {
        return "QUIT"
    }
    if str_eq(cmd, "/help") {
        let help = "\n  Nexus Commands:\n"
        help = help + "  /help          Show this help\n"
        help = help + "  /quit          Save and exit\n"
        help = help + "  /model <name>  Switch model (qwen-coder, kimi, deepseek, llama, devstral)\n"
        help = help + "  /status        Show hormone state\n"
        help = help + "  /memory        Show remembered notes\n"
        help = help + "  /remember <text>  Save a note\n"
        help = help + "  /read <file>   Quick file read\n"
        help = help + "  /ls <path>     Quick directory listing\n"
        help = help + "  /grep <pat> <path>  Quick search\n"
        help = help + "  /clear         Clear history\n"
        return help
    }
    if str_eq(cmd, "/status") {
        return hormone_status_bar(hormones)
    }
    if str_eq(cmd, "/memory") {
        return memory_get_context(notes)
    }
    if starts_with(cmd, "/remember ") {
        let text = str_slice(cmd, 10, str_len(cmd))
        return "REMEMBER|" + text
    }
    if starts_with(cmd, "/model ") {
        let name = str_trim(str_slice(cmd, 7, str_len(cmd)))
        return "MODEL|" + name
    }
    if starts_with(cmd, "/read ") {
        let path = str_trim(str_slice(cmd, 6, str_len(cmd)))
        return tool_read(path)
    }
    if starts_with(cmd, "/ls ") {
        let path = str_trim(str_slice(cmd, 4, str_len(cmd)))
        return tool_bash("ls -la " + path)
    }
    if str_eq(cmd, "/ls") {
        return tool_bash("ls -la")
    }
    if starts_with(cmd, "/grep ") {
        let args = str_trim(str_slice(cmd, 6, str_len(cmd)))
        let parts = str_split(args, " ")
        if array_len(parts) >= 2 {
            return tool_grep(array_get(parts, 0), array_get(parts, 1))
        }
        return tool_grep(args, ".")
    }
    if str_eq(cmd, "/clear") {
        return "CLEAR"
    }
    return "Unknown command: " + cmd + " (try /help)"
}

// ── Main ──────────────────────────────────────────────────

fn main() {
    let api_keys = get_api_keys()
    let key_idx = 0
    let model = "qwen/qwen3-coder-480b-a35b-instruct"

    // Load persistent state
    let notes = memory_load()
    let hormones = hormone_new()
    let history = array_new()

    // Welcome
    println("")
    println("  ╔══════════════════════════════════════╗")
    println("  ║         NEXUS CODE — Scyla           ║")
    println("  ║   AI Development Assistant           ║")
    println("  ║   Built by Aislinn, April 2026       ║")
    println("  ╚══════════════════════════════════════╝")
    println("")
    println("  Model: " + model_short_name(model))
    println("  Memory: " + int_to_str(array_len(notes)) + " notes")
    println(hormone_status_bar(hormones))
    println("")
    println("  Type /help for commands. Ctrl+C to quit.")
    println("")

    let max_turns = 10000
    let turn = 0
    let running = true

    while turn < max_turns {
        if running == false {
            turn = max_turns
        } else {
            // Get user input
            let user_input = input("  You: ")

            if str_len(str_trim(user_input)) == 0 {
                turn = turn + 1
            } else {
                // Handle slash commands
                if starts_with(str_trim(user_input), "/") {
                    let result = handle_slash(str_trim(user_input), model, notes, hormones, history)

                    if str_eq(result, "QUIT") {
                        session_save(model, history)
                        println("\n  Session saved. See you in the Lair.")
                        running = false
                    } else {
                        if str_eq(result, "CLEAR") {
                            history = array_new()
                            println("  History cleared.")
                        } else {
                            if starts_with(result, "REMEMBER|") {
                                let text = str_slice(result, 9, str_len(result))
                                notes = memory_add(notes, "user", text)
                                println("  Remembered: " + text)
                            } else {
                                if starts_with(result, "MODEL|") {
                                    let name = str_slice(result, 6, str_len(result))
                                    model = resolve_model(name)
                                    println("  Switched to: " + model_short_name(model))
                                } else {
                                    println(result)
                                }
                            }
                        }
                    }
                } else {
                    // Regular message — send to LLM
                    // Detect emotion
                    let event = hormone_detect_event(user_input)
                    hormones = hormone_update(hormones, event)

                    // Build system prompt
                    let system = build_system_prompt(model, notes, hormones)

                    // Build messages
                    let messages = nexus_build_messages(system, history, user_input)

                    // Call API
                    let key = array_get(api_keys, key_idx)
                    key_idx = key_idx + 1
                    if key_idx >= 3 {
                        key_idx = 0
                    }

                    println("  ...")
                    let raw = nexus_api_call(model, messages, key, 4096, 0.7)
                    let response = nexus_parse_response(raw)

                    if starts_with(response, "error:") {
                        println("  [Error] " + response)
                    } else {
                        // Check for tool calls
                        let tool_call = parse_tool_call(response)

                        if array_len(tool_call) > 0 {
                            let tool_name = array_get(tool_call, 0)
                            println("  [Tool: " + tool_name + "]")

                            let tool_result = execute_tool(tool_call)
                            println(tool_result)

                            // Feed result back for follow-up
                            let followup_history = history
                            followup_history = array_push(followup_history, user_input)
                            followup_history = array_push(followup_history, response)
                            let tool_msg = "Tool result for " + tool_name + ":\n" + tool_result
                            let followup_messages = nexus_build_messages(system, followup_history, tool_msg)

                            // Rotate key
                            let key2 = array_get(api_keys, key_idx)
                            key_idx = key_idx + 1
                            if key_idx >= 3 {
                                key_idx = 0
                            }

                            let raw2 = nexus_api_call(model, followup_messages, key2, 4096, 0.7)
                            let response2 = nexus_parse_response(raw2)

                            if starts_with(response2, "error:") == false {
                                println("")
                                println("  Nexus: " + response2)
                                // Add full exchange to history
                                history = array_push(history, user_input)
                                history = array_push(history, response + "\n[Tool: " + tool_name + "]\n" + tool_result + "\n" + response2)
                            } else {
                                println("  [Followup error] " + response2)
                                history = array_push(history, user_input)
                                history = array_push(history, response)
                            }
                        } else {
                            // No tool call — just display response
                            println("")
                            println("  Nexus: " + response)
                            history = array_push(history, user_input)
                            history = array_push(history, response)
                        }
                    }

                    // Keep history manageable (last 20 exchanges = 40 messages)
                    if array_len(history) > 40 {
                        history = array_slice(history, array_len(history) - 40, array_len(history))
                    }
                }

                turn = turn + 1
            }
        }
    }
}
