require("lua/lemon")

local def_workspace = { args = {}, build_type = "debug", binary = "blog-server" }
local workspace = InitWorkspace(def_workspace)

local build_folder
local bin_target
local bin_name

local function updateBuildEnv()
  build_folder = './target/' .. workspace.build_type
  bin_target = workspace.binary
  bin_name = build_folder .. '/' .. bin_target

  -- The run (F6) arguments
  vim.opt.makeprg = "cargo build"
  vim.g.cargo_makeprg_params = 'build'
  if workspace.build_type == "release" then
    vim.opt.makeprg = vim.opt.makeprg .. " --release"
    vim.g.cargo_makeprg_params = vim.g.cargo_makeprg_params .. " --release"
  end

  -- Rust compiler error format
  vim.opt.errorformat = {
    -- Main error/warning line with file:line:col format
    '%E%>error%m,' ..        -- Start of error block
    '%W%>warning: %m,' ..    -- Start of warning block
    '%-G%>help: %m,' ..      -- Ignore help lines
    '%-G%>note: %m,' ..      -- Ignore note lines
    '%C%>  --> %f:%l:%c,' .. -- Continuation: file location
    '%Z%>%p^%m,' ..          -- End: column pointer (^^^)
    '%C%>%s%#|%.%#,' ..      -- Continuation: context lines with |
    '%C%>%s%#%m,' ..         -- Continuation: other context
    '%-G%.%#'                -- Ignore everything else
  }
end

updateBuildEnv()

-- Prevent Vim's built-in rust ftplugin from loading the cargo compiler
vim.api.nvim_create_autocmd("FileType", {
  pattern = "rust",
  callback = function()
    vim.b.current_compiler = 'custom'
  end,
})

-- nvim-dap configuration
local dap_ok, dap = pcall(require, "dap")
local dap_def_cfg
local dap_configs

-- Update args for both run and debug configs
local function updateArgs(args)
  workspace.args = args
  if dap_configs ~= nil then dap_configs[1].args = args end
  WriteWorkspace()
end

-- The Configure command
vim.api.nvim_create_user_command("Configure", function(a)
  local args = {}
  local bt = "debug"
  if #a.args > 0 then bt = a.args end
  workspace.build_type = bt
  updateBuildEnv()
  WriteWorkspace()
end, { nargs = '?', desc = "Update run/debug arguments" })

vim.api.nvim_create_user_command("Args", function(a) updateArgs(a.fargs) end,
  { nargs = '*', desc = "Update run/debug arguments" })

if dap_ok then
  local rust_path = vim.fn.system("rustc --print sysroot") -- We need to query this to get the sysroot
  rust_path = string.sub(rust_path, 1, #rust_path - 1)     -- trim trailing newline
  local lldb_init = {
    "command script import " .. rust_path .. "/lib/rustlib/etc/lldb_lookup.py",
    "command source " .. rust_path .. "/lib/rustlib/etc/lldb_commands",
  }
  dap_configs = {
    {
      name = 'default',
      type = 'codelldb',
      request = 'launch',
      program = bin_name,
      args = workspace.args,
      cwd = '${workspaceFolder}',
      stopOnEntry = false,
      initCommands = lldb_init
    }
  }
  dap_def_cfg = dap_configs[1]
  dap.providers.configs["project"] = function()
    return dap_configs
  end

  -- DebugArgs to set debugger arguments and run immediately
  vim.api.nvim_create_user_command("DebugArgs", function(a)
    updateArgs(a.fargs)
    dap.run(dap_configs[1])
  end, { nargs = '*', desc = "Starts debugging with specified arguments" })
end

local r = function()
  MakeAnd(function()
    TermRun(bin_name .. " " .. table.concat(workspace.args, " "))
  end)
end
-- RunArgs sets the run arguments that F6 uses and reruns immediately
vim.api.nvim_create_user_command("RunArgs", function(a)
  updateArgs(a.fargs)
  r()
end, { nargs = '*', desc = "Starts debugging with specified arguments" })

-- F6 to run the application
vim.keymap.set('n', '<F6>', r)
vim.keymap.set('n', '<F18>', function()
  local info = GetTermInfo()
  if info then
    -- Send interrupt to terminal without switching
    vim.fn.chansend(info.job_id, '\003')
    -- Close window if it's open
    vim.print("Stopped program")
  else
    vim.print("No terminal buffer found")
  end
end)

if dap_ok then
  -- Shift-F5 to launch default config
  vim.keymap.set('n', '<F17>', function()
    MakeAnd(function()
      dap.run(dap_def_cfg)
    end)
  end)
end
