import tempfile
from pathlib import Path

from brokk_code.zed_config import ExistingBrokkCodeEntryError

_NVIM_CODECOMPANION_TEMPLATE = """-- Generated by `brokk install nvim`
-- Requires codecompanion.nvim to already be installed in Neovim.
-- https://github.com/olimorris/codecompanion.nvim
-- Load this module from your CodeCompanion setup:
-- require("codecompanion").setup(require("brokk.brokk_codecompanion"))

local acp_helpers = require("codecompanion.adapters.acp.helpers")

return {
  interactions = {
    chat = {
      adapter = "brokk",
    },
  },
  adapters = {
    acp = {
      brokk = function()
        return {
          name = "brokk",
          formatted_name = "Brokk",
          type = "acp",
          roles = {
            llm = "assistant",
            user = "user",
          },
          -- Uses uvx to always run the latest version of brokk
          commands = {
            default = {
              "uvx",
              "brokk",
              "acp",
            },
          },
          defaults = {
            mcpServers = {},
            timeout = 20000,
          },
          env = {},
          parameters = {
            protocolVersion = 1,
            clientCapabilities = {
              fs = { readTextFile = true, writeTextFile = true },
            },
            clientInfo = {
              name = "CodeCompanion.nvim",
              version = "1.0.0",
            },
          },
          handlers = {
            setup = function(self)
              return true
            end,
            form_messages = function(self, messages, capabilities)
              return acp_helpers.form_messages(self, messages, capabilities)
            end,
            on_exit = function(self, code) end,
          },
        }
      end,
    },
  },
}
"""


def _default_nvim_codecompanion_path() -> Path:
    return Path.home() / ".config" / "nvim" / "lua" / "brokk" / "brokk_codecompanion.lua"


def _atomic_write_text(path: Path, text: str) -> None:
    with tempfile.NamedTemporaryFile(
        mode="w",
        encoding="utf-8",
        dir=path.parent,
        prefix=f".{path.name}.",
        suffix=".tmp",
        delete=False,
    ) as temp_file:
        temp_file.write(text)
        temp_path = Path(temp_file.name)

    if path.exists():
        temp_path.chmod(path.stat().st_mode)
    temp_path.replace(path)


def configure_nvim_codecompanion_acp_settings(
    *, force: bool = False, settings_path: Path | None = None
) -> Path:
    path = settings_path or _default_nvim_codecompanion_path()
    if path.exists() and not force:
        raise ExistingBrokkCodeEntryError(f"{path} already exists; use --force to overwrite it")

    path.parent.mkdir(parents=True, exist_ok=True)
    _atomic_write_text(path, _NVIM_CODECOMPANION_TEMPLATE)
    return path
