local lsp = require('lspconfig')
local util = lsp.util

local lspcap = require('cmp_nvim_lsp')
  .default_capabilities(vim.lsp.protocol.make_client_capabilities())
local lspatt = function(client, bufnr)
  vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc')
  -- disabling semantic highlighting for omnisharp https://github.com/OmniSharp/omnisharp-roslyn/issues/2483
  if client.name == "omnisharp" then

    local tokenModifiers = client.server_capabilities.semanticTokensProvider.legend.tokenModifiers
    for i, v in ipairs(tokenModifiers) do
      local tmp = string.gsub(v, ' ', '_')
      tokenModifiers[i] = string.gsub(tmp, '-_', '')
    end
    local tokenTypes = client.server_capabilities.semanticTokensProvider.legend.tokenTypes
    for i, v in ipairs(tokenTypes) do
      local tmp = string.gsub(v, ' ', '_')
      tokenTypes[i] = string.gsub(tmp, '-_', '')
    end

    --client.server_capabilities.semanticTokensProvider = {
    --  legend = {},
    --  vim_lsp_semantic_tokens = {},
    --}
  end
end

-- color scheme setup
vim.g.catppuccin_flavour = 'mocha'
require('catppuccin').setup()
vim.cmd [[colorscheme catppuccin]]

-- load snippets
require('luasnip.loaders.from_snipmate').lazy_load({
  paths = "~/.config/nvim/snippets"
})

-- replace built in selector with telescope
local fb_actions = require'telescope'.extensions.file_browser.actions
require('telescope').setup {
  extensions = {
    ["ui-select"] = {
      require("telescope.themes").get_dropdown {}
    },
    file_browser = {
      initial_mode = "normal",
      hijack_netrw = true,
      dir_icon = "",
      mappings = {
        ["i"] = {
          ["<A-c>"] = false,
          ["<S-CR>"] = false,
          ["<A-r>"] = false,
          ["<A-m>"] = false,
          ["<A-y>"] = false,
          ["<A-d>"] = false,
          ["<C-o>"] = false,
          ["<C-g>"] = false,
          ["<C-e>"] = false,
          ["<C-w>"] = false,
          ["<C-t>"] = false,
          ["<C-f>"] = false,
          ["<C-h>"] = false,
          ["<C-s>"] = false,
          ["<Tab>"] = false,
          ["<S-Tab>"] = false,
          ["<bs>"] = false,
        },
        ["n"] = {
          c = false,
          r = false,
          m = false,
          y = false,
          d = false,
          o = false,
          g = false,
          e = false,
          w = false,
          t = false,
          f = false,
          s = false,
          h = fb_actions.toggle_hidden,
          ["<Tab>"] = false,
          ["<S-Tab>"] = false,
          ["-"] = fb_actions.goto_parent_dir,
          ["/"] = function()
            vim.cmd('startinsert')
          end,
          ["+"] = fb_actions.create,
        },
      },
    },
  }
}
require('telescope').load_extension('ui-select')
require('telescope').load_extension('file_browser')

-- autocomplete config
local cmp = require 'cmp'
cmp.setup {
  snippet = {
    expand = function(args)
      require'luasnip'.lsp_expand(args.body)
    end,
  },
  mapping = {
    ['<Tab>'] = cmp.mapping.select_next_item(),
    ['<S-Tab>'] = cmp.mapping.select_prev_item(),
    ['<CR>'] = cmp.mapping.confirm({
      behavior = cmp.ConfirmBehavior.Replace,
      select = false,
    })
  },
  preselect = cmp.PreselectMode.None,
  confirmation = { get_commit_characters = function(_) return {} end },
  sources = {
    { name = 'nvim_lsp' },
    { name = 'luasnip' },
    { name = 'buffer' },
    { name = 'path' },
  },
}

-- gitsigns
require('gitsigns').setup()

-- lsp configs
lsp.openscad_ls.setup {
  capabilities = lspcap,
  on_attach = lspatt,
}
lsp.omnisharp.setup {
  capabilities = lspcap,
  on_attach = lspatt,
  root_dir = function(file, _)
    if file:sub(-#".csx") == ".csx" then
      return util.path.dirname(file)
    end
    return util.root_pattern("*.sln")(file) or util.root_pattern("*.csproj")(file) or util.root_pattern("omnisharp.json")(file)
  end,
  cmd = { "/usr/bin/omnisharp" }, --"--languageserver" , "--hostPID", tostring(pid) },
}
lsp.tsserver.setup {
  capabilities = lspcap,
  on_attach = lspatt,
  cmd = { "npx", "typescript-language-server", "--stdio" },
}
lsp.yamlls.setup {
  capabilities = lspcap,
  on_attach = lspatt,
}
lsp.ccls.setup {
  capabilities = lspcap,
  on_attach = lspatt,
}
local runtime_path = vim.split(package.path, ';')
table.insert(runtime_path, "lua/?.lua")
table.insert(runtime_path, "lua/?/init.lua")
lsp.lua_ls.setup {
  capabilities = lspcap,
  on_attach = lspatt,
  cmd = { "lua-language-server", "-E" },
  settings = {
    Lua = {
      runtime = {
        version = 'LuaJIT',
        path = runtime_path,
      },
      diagnostics = {
        globals = {'vim', 'use'},
      },
      workspace = {
        library = vim.api.nvim_get_runtime_file("", true),
      },
      telemetry = {
        enable = false,
      },
    },
  }
}
lsp.perlpls.setup {
  capabilities = lspcap,
  on_attach = lspatt,
  settings = {
    perl = {
      perlcritic = {
        enabled = false
      },
      syntax = {
        enabled = true
      }
    }
  }
}
lsp.efm.setup {
  capabilities = lspcap,
  on_attach = lspatt,
  filetypes = {"sh", "markdown"},
  settings = {
    languages = {
      sh = {{
        lintCommand = "shellcheck -f gcc -x",
        lintSource = "shellcheck",
        lintFormats = { "%f:%l:%c: %trror: %m", "%f:%l:%c: %tarning: %m", "%f:%l:%c: %tote: %m" },
        lintIgnoreExitCode = true
      }},
      markdown = {{
        lintCommand = "write-good --parse",
        lintSource = "write-good",
        lintFormats = { "%f:%l:%c:%m" },
      }},
    }
  }
}
lsp.pyright.setup {
  capabilities = lspcap,
  on_attach = lspatt,
}
-- setup for Arduboy dev
lsp.arduino_language_server.setup {
  capabilities = lspcap,
  on_attach = lspatt,
  cmd = {
    "arduino-language-server",
    "-cli-config", "~/.arduino15/arduino-cli.yaml",
    "-cli", "/bin/arduino-cli",
    "-clangd", "/usr/bin/clangd",
    "-fqbn", "arduino:avr:leonardo"
  },
}

-- status line setup
require'lualine'.setup {
  options = {
    theme = 'catppuccin',
    component_separators = { left = '', right = '' },
    section_separators = { left = '', right = '' },
  },
  sections = {
    lualine_a = {'mode'},
    lualine_b = {'branch'},
    lualine_c = {{
      'filename',
      symbols = {
        modified = '✎ ',
        readonly = '🔒 ',
        unnamed = '[No Name]'
      }
    }},
    lualine_x = {{
      "diagnostics",
      sources = {"nvim_lsp"},
      icons_enabled = true
    }},
    lualine_y = {'progress'},
    lualine_z = {'location'},
  }
}

-- zen mode config
require('true-zen').setup {
  modes = {
    ataraxis = {
      callbacks = {
        open_pre = function()
          vim.opt.linebreak = true
          vim.opt.spell = true
        end,
        close_post = function()
          vim.opt.linebreak = false
          vim.opt.spell = false
        end
      }
    }
  },
  integrations = {
    tmux = true,
    lualine = true
  }
}

-- debug adapter protocol for .net core
local dap = require('dap')
dap.adapters.coreclr = {
  type = 'executable',
  command = '/home/rudism/.local/bin/netcoredbg',
  args = {'--interpreter=vscode'},
}
dap.configurations.cs = {{
  type = "coreclr",
  name = "launch - netcoredbg",
  request = "launch",
  program = function()
    return vim.fn.input('Path to dll', vim.fn.getcwd() .. '/bin/Debug/', 'file')
  end,
}}
