--- Helpers to build the command and context around running a single test.

local dap = require("neotest-golang.features.dap")
local find = require("neotest-golang.lib.find")
local lib = require("neotest-golang.lib")
local logger = require("neotest-golang.lib.logging")
local options = require("neotest-golang.options")

local M = {}

--- Build runspec for a single test
--- @param pos neotest.Position Position data for the test
--- @param tree neotest.Tree Neotest tree containing test structure
--- @param strategy string|nil Strategy to use (e.g., "dap" for debugging)
--- @return neotest.RunSpec|nil Runspec for executing the test
function M.build(pos, tree, strategy)
  local pos_path_folderpath = lib.path.get_directory(pos.path)

  local golist_data, golist_error = lib.cmd.golist_data(pos_path_folderpath)

  local errors = nil
  if golist_error ~= nil then
    if errors == nil then
      errors = {}
    end
    table.insert(errors, golist_error)
  end

  local test_name = lib.convert.pos_id_to_go_test_name(pos.id)
  if not test_name then
    logger.error("Could not determine test name for position id: " .. pos.id)
    return nil
  end
  local test_name_regex = lib.convert.to_gotest_regex_pattern(test_name)

  local test_cmd, json_filepath = lib.cmd.test_command_in_package_with_regexp(
    pos_path_folderpath,
    test_name_regex
  )

  local runspec_strategy = nil
  if strategy == "dap" then
    dap.assert_dap_prerequisites()
    runspec_strategy = dap.get_dap_config(pos_path_folderpath, test_name_regex)
    logger.debug("DAP strategy used: " .. vim.inspect(runspec_strategy))
    dap.setup_debugging(pos_path_folderpath)
  end

  local env = lib.extra_args.get().env or options.get().env
  if type(env) == "function" then
    env = env()
  end

  local stream, stop_filestream =
    lib.stream.new(tree, golist_data, json_filepath)

  --- @type RunspecContext
  local context = {
    pos_id = pos.id,
    golist_data = golist_data,
    errors = errors,
    process_test_results = true,
    test_output_json_filepath = json_filepath,
    stop_filestream = stop_filestream,
  }

  --- @type neotest.RunSpec
  local run_spec = {
    command = test_cmd,
    cwd = pos_path_folderpath,
    context = context,
    env = env,
    stream = stream,
  }

  if runspec_strategy ~= nil then
    run_spec.strategy = runspec_strategy
    run_spec.context.is_dap_active = true
  end

  logger.debug({ "RunSpec:", run_spec })
  return run_spec
end

return M
