local plugins = require 'goldsmith.plugins'
local config = require 'goldsmith.config'
local tools = require 'goldsmith.tools'
local servers = require 'goldsmith.lsp.servers'
local log = require 'goldsmith.log'

local M = {}

local running_services = {}

local function service_module(name)
  return require(string.format('goldsmith.autoconfig.lsp.null.%s', name))
end

function M.supported_filetypes()
  return servers.info('null').filetypes
end

function M.is_minimum_version()
  return true
end

function M.has_requirements()
  if plugins.is_installed 'null' then
    return true
  end
  return false
end

function M.map(f)
  for _, s in ipairs(M.services()) do
    local m = service_module(s)
    f(s, m)
  end
end

function M.services()
  return tools.names { null = true }
end

function M.running_services()
  local rs = {}
  for _, v in pairs(running_services) do
    table.insert(rs, v.name)
  end
  return rs
end

function M.is_disabled(service)
  if config.get('null', 'enabled') == false then
    return true
  end
  if service ~= nil then
    return config.service_is_disabled(service)
  end
  return false
end

function M.setup()
  local null = require 'null-ls'
  local enabled_services = 0
  for _, service in ipairs(M.services()) do
    local m = service_module(service)
    if not M.is_disabled(service) then
      if m.has_requirements() then
        local setup
        local user_args = config.get('null', service)
        if type(user_args) == 'table' then
          setup = m.setup(user_args['args'] or {})
          if user_args['config_file'] then
            m.config_file = function()
              return user_args['config_file']
            end
          end
          if user_args['suppress_errors'] then
            m.suppress_errors = function()
              return user_args['suppress_errors']
            end
          end
        else
          setup = m.setup {}
        end
        table.insert(running_services, setup)
        null.register(setup)
        enabled_services = enabled_services + 1
      else
        log.warn(
          'Null',
          string.format(
            "'%s' is not installed. Any service that requires it will not function. Run ':checkhealth goldsmith' for more.",
            service
          )
        )
      end
    end
  end
  if enabled_services == 0 then
    M.is_disabled = function()
      return true
    end
  end
end

-- basic setup
function M.pre(cf)
  local null = require 'null-ls'
  if config.get('null', 'run_setup') then
    null.setup(cf)
  end
  return cf
end

return M
