local common = require('lsp.common')

function goimports(timeout_ms)
    local context = { only = { "source.organizeImports" } }
    vim.validate { context = { context, "t", true } }

    local params = vim.lsp.util.make_range_params()
    params.context = context

    -- See the implementation of the textDocument/codeAction callback
    -- (lua/vim/lsp/handler.lua) for how to do this properly.
    local results = vim.lsp.buf_request_sync(0, "textDocument/codeAction", params, timeout_ms)
    if not results or next(results) == nil then return end
    local actions
    for i, result in pairs(results) do
        if result then
            actions = result.result
            break
        end
    end
    print(vim.inspect(actions))
    if not actions then return end
    local action = actions[1]

    -- textDocument/codeAction can return either Command[] or CodeAction[]. If it
    -- is a CodeAction, it can have either an edit, a command or both. Edits
    -- should be executed first.
    if action.edit or type(action.command) == "table" then
        if action.edit then
            vim.lsp.util.apply_workspace_edit(action.edit)
        end
        if type(action.command) == "table" then
            vim.lsp.buf.execute_command(action.command)
        end
    else
        vim.lsp.buf.execute_command(action)
    end
end

function format_with_imports(timeout_ms)
    goimports(1000)
    vim.lsp.buf.formatting()
end

vim.cmd [[
    augroup gopls
        autocmd!
        autocmd BufWritePre *.go lua format_with_imports(1000)
    augroup END
]]

require('lspconfig').gopls.setup {
    capabilities = common.cap,
    on_attach = common.attach,
    flags = {
        debounce_text_changes = 150,
    },
    settings = {
        gopls = {
            gofumpt = true,
            usePlaceholders = true,
            completeUnimported = true,
            experimentalPostfixCompletions = true,
            analyses = {
                assign = true,
                atomic = true,
                atomicalign = true,
                bools = true,
                buildtag = true,
                composites = true,
                copylocks = true,
                erroras = true,
                fieldalignment = true,
                httpresponse = true,
                ifaceassert = true,
                infertypeargs = true,
                loopclosure = true,
                lostcancel = true,
                nilfunc = true,
                nilness = true,
                printf = true,
                shadow = true,
                simplifyrange = true,
                simplifyslice = true,
                sortslice = true,
                stdmethods = true,
                stringintconv = true,
                testinggoroutine = true,
                tests = true,
                unmarshal = true,
                unreachable = true,
                unsafeptr = true,
                unusedparams = true,
                unusedresult = true,
                unusedwrite = true,
                useany = true,
                nonewvars = true,
            },
        },
    },
}

-- Change local setting to separate 3rd-party and local imports with go.mod prefix
