local vim = vim
local api = vim.api

local is_new_handler = function(arg)
  -- For neovim 0.6 breaking changes
  -- https://github.com/neovim/neovim/pull/15504
  return vim.fn.has('nvim-0.6') and type(arg) == 'table'
end

local respond = function(item)
  api.nvim_call_function('signature_help#notify', {'respond', {item}})
end

local get_available_client = function()
  for _, client in pairs(vim.lsp.get_clients({ bufnr = api.nvim_get_current_buf() })) do
    if client.server_capabilities and client.server_capabilities.signatureHelpProvider then
      return client
    end
  end
  return nil
end

local request_signature_help = function(arg)
  local client = get_available_client()
  if client == nil then
    return
  end
  local encoding = client.offset_encoding
  local params = vim.lsp.util.make_position_params(0, encoding)
  client:request("textDocument/signatureHelp", params, function(_, arg1, arg2)
    local res = is_new_handler(arg1) and arg1 or arg2
    if res and not vim.tbl_isempty(res) and res.signatures and res.signatures[1] then
      respond(res)
    else
      api.nvim_call_function("signature_help#doc#close_floating", {})
    end
  end)
end

local get_capabilities = function()
  local caps = {}
  for _, client in pairs(vim.lsp.get_clients({ bufnr = api.nvim_get_current_buf() })) do
    if client.server_capabilities then
      table.insert(caps, client.server_capabilities)
    end
  end
  return caps
end

return {
  request_signature_help = request_signature_help,
  get_capabilities = get_capabilities,
}
