local TOOLCHAINS = {}

------------
-- Plugins -
------------

local plugins = {}

--- @param ... LazySpec
function TOOLCHAINS.add_plugins(...)
    for _, spec in ipairs({ ... }) do
        table.insert(plugins, spec)
    end
end

function TOOLCHAINS.get_plugins()
    return plugins
end

---------
-- LSPs -
---------
local lsp_autoinstalls = {}
local lsp_setups = {}

--- @param ... string
function TOOLCHAINS.add_lsp_autoinstalls(...)
    for _, lsp in ipairs({ ... }) do
        table.insert(lsp_autoinstalls, lsp)
    end
end

function TOOLCHAINS.get_lsp_autoinstalls()
    return lsp_autoinstalls
end

--- @param setup SetupLSPs
function TOOLCHAINS.add_lsps(setup)
    table.insert(lsp_setups, setup)
end

--- @param lspconfig any
--- @param capabilities any
function TOOLCHAINS.setup_lsps(lspconfig, capabilities)
    for _, setup in ipairs(lsp_setups) do
        setup(lspconfig, capabilities)
    end
end

------------
-- Null ls -
------------

local null_ls_setups = {}

--- @param setup SetupNullLsModule
function TOOLCHAINS.add_null_ls_module(setup)
    table.insert(null_ls_setups, setup)
end

function TOOLCHAINS.get_null_ls_source(null_ls)
    local null_ls_sources = {}
    for _, setup_function in ipairs(null_ls_setups) do
        local conf = setup_function(null_ls)
        if #conf ~= 0 then
            for _, _conf in pairs(conf) do
                table.insert(null_ls_sources, _conf)
            end
        end
    end
    return null_ls_sources
end

----------------
-- Highlighter -
----------------

local highlighter_autoinstalls = {}

--- @param ... string
function TOOLCHAINS.add_highlighter_autoinstalls(...)
    for _, highlighter in ipairs({ ... }) do
        table.insert(highlighter_autoinstalls, highlighter)
    end
end

function TOOLCHAINS.get_highlighter_autoinstalls()
    return highlighter_autoinstalls
end

--------------
-- Debugging -
--------------

local debug_adapters = {}
local debug_configs = {}

---@param name string
---@param adapter dap.Adapter
function TOOLCHAINS.add_debug_adapter(name, adapter)
    debug_adapters[name] = adapter
end

---@param name string
---@param config dap.Configuration
function TOOLCHAINS.add_debug_config(name, config)
    debug_configs[name] = config
end

---@param adapters table<string, dap.Adapter>
---@param configs table<string, dap.Configuration>
function TOOLCHAINS.setup_debuggers(adapters, configs)
    for name, adapter in pairs(debug_adapters) do
        adapters[name] = adapter
    end
    for name, config in pairs(debug_configs) do
        configs[name] = config
    end
end

---------
-- Init -
---------
function TOOLCHAINS.init()
    require('toolchain.config').setup()
    require('toolchain.database').setup()
    require('toolchain.frontend').setup()
    require('toolchain.generic').setup()
    require('toolchain.git').setup()
    require('toolchain.go').setup()
    require('toolchain.lua').setup()
    require('toolchain.php').setup()
    require('toolchain.rust').setup()
    require('toolchain.scripts').setup()
    require('toolchain.text').setup()
    require('toolchain.web').setup()
    require('toolchain.angular').setup()
    require('toolchain.java').setup()
end

return TOOLCHAINS

---------------------
-- Type Definitions -
---------------------
---@alias SetupLSPs fun(lspconfig:any, capabilities: any)
---@alias SetupNullLsModule fun(null_ls: any):table