-- debug.lua
--
-- Shows how to use the DAP plugin to debug your code.
--
-- Primarily focused on configuring the debugger for Go, but can
-- be extended to other languages as well. That's why it's called
-- kickstart.nvim and not kitchen-sink.nvim ;)

return {
  {
    -- NOTE: Yes, you can install new plugins here!
    'mfussenegger/nvim-dap',
    -- NOTE: And you can specify dependencies as well
    dependencies = {
      -- Creates a beautiful debugger UI

      -- Required dependency for nvim-dap-ui
      'nvim-neotest/nvim-nio',

      -- Installs the debug adapters for you
      'williamboman/mason.nvim',
      'jay-babu/mason-nvim-dap.nvim',

      'theHamsta/nvim-dap-virtual-text',
    },
    config = function()
      local dap = require 'dap'
      local dapui = require 'dapui'

      require('mason-nvim-dap').setup {
        -- Makes a best effort to setup the various debuggers with
        -- reasonable debug configurations
        automatic_installation = true,

        -- You can provide additional configuration to the handlers,
        -- see mason-nvim-dap README for more information
        handlers = {},

        -- You'll need to check that you have the required things installed
        -- online, please don't ask me how to install them :)
        ensure_installed = {
          -- Update this to ensure that you have the debuggers for the langs you want
          'codelldb',
          'debugpy',
        },
      }

      -- Basic debugging keymaps, feel free to change to your liking!
      vim.keymap.set('n', '<leader>dB', function() end, { desc = 'Debug: Set Breakpoint' })

      -- Dap UI setup
      -- For more information, see |:help nvim-dap-ui|
      dapui.setup {
        -- Set icons to characters that are more likely to work in every terminal.
        --    Feel free to remove or use ones that you like more! :)
        --    Don't feel like these are good choices.
        icons = { expanded = '▾', collapsed = '▸', current_frame = '*' },
        controls = {
          icons = {
            pause = '⏸',
            play = '▶',
            step_into = '⏎',
            step_over = '⏭',
            step_out = '⏮',
            step_back = 'b',
            run_last = '▶▶',
            terminate = '⏹',
            disconnect = '⏏',
          },
        },
      }

      dap.listeners.after.event_initialized['dapui_config'] = dapui.open
      dap.listeners.before.event_terminated['dapui_config'] = dapui.close
      dap.listeners.before.event_exited['dapui_config'] = dapui.close
    end,
  },
  {
    'rcarriga/nvim-dap-ui',
    keys = {
      {
        '<leader>du',
        function()
          require('dapui').toggle()
        end,

        desc = 'Open [D]ebug [U]i',
      },
      {
        '<leader>dso',
        function()
          require('dap').step_over()
        end,

        desc = 'Toggle [D]ebug [S]tep [O]ver',
      },
      {
        '<leader>dsi',
        function()
          require('dap').step_into()
        end,

        desc = 'Toggle [D]ebug [S]tep [I]nto',
      },
      {
        '<leader>dc',
        function()
          require('dap').continue()
        end,

        desc = 'Toggle [D]ebug [C]ontinue / Start',
      },
      {
        '<leader>db',
        function()
          require('dap').toggle_breakpoint()
        end,

        desc = 'Toggle [D]ebug [B]reakpoint',
      },
      {
        '<leader>dB',
        function()
          require('dap').set_breakpoint(vim.fn.input 'Breakpoint condition: ')
        end,

        desc = 'Toggle [D]ebug [B]reakpoint condition',
      },
      {
        '<leader>dK',
        function()
          require('dap.ui.widgets').hover()
        end,

        desc = 'Open [D]ebug [K] hover',
      },
      {
        '<leader>dws',
        function()
          local widgets = require 'dap.ui.widgets'
          local my_sidebar = widgets.sidebar(widgets.scopes)
          my_sidebar.open()
        end,
        desc = 'Open [D]ebug [W]indow [S]copes',
      },
      {
        '<leader>dwr',
        function()
          require('dap').repl.toggle()
        end,

        desc = 'Open [D]ebug [W]indow [R]epl',
      },
      {
        '<leader>dwf',
        function()
          local widgets = require 'dap.ui.widgets'
          local my_sidebar = widgets.sidebar(widgets.frames)
          my_sidebar.open()
        end,

        desc = 'Open [D]ebug [W]indow [F]rames',
      },
      {
        '<leader>dwi',
        function()
          local widgets = require 'dap.ui.widgets'
          local my_sidebar = widgets.sidebar(widgets.sessions)
          my_sidebar.open()
        end,
        desc = 'Open [D]ebug [W]indow sess[I]ons',
      },
      {
        '<leader>dwt',
        function()
          local widgets = require 'dap.ui.widgets'
          local my_sidebar = widgets.sidebar(widgets.threads)
          my_sidebar.open()
        end,
        desc = 'Open [D]ebug [W]indow [T]hreads',
      },
      {
        '<leader>dwe',
        function()
          local widgets = require 'dap.ui.widgets'
          local my_sidebar = widgets.sidebar(widgets.expression)
          my_sidebar.open()
        end,

        desc = 'Open [D]ebug [W]indow [E]xpression',
      },
    },
    dependencies = {
      'mfussenegger/nvim-dap',
      'nvim-neotest/nvim-nio',
    },
    config = function(_, opts)
      local dap = require 'dap'
      local dapui = require 'dapui'
      dapui.setup(opts)
      dap.listeners.after.event_initialized['dapui_config'] = function()
        dapui.open {}
      end
      dap.listeners.before.event_terminated['dapui_config'] = function()
        -- dapui.close {}
      end
      dap.listeners.before.event_exited['dapui_config'] = function()
        -- dapui.close {}
      end
    end,
  },
}
