require('core.snippets.shorthands')

--- create a decleration of a function from it's definition using treesitter
---@param func string
---@return string|nil
local function c_func(func)
  local tree = vim.treesitter.get_parser():parse()[1]:root()

  local q = vim.treesitter.query.parse("c", "(function_definition) @f")
  local matches = q:iter_matches(tree, 0)

  vim.treesitter.query.parse("c", "(identifier) @i")
  local m = q:iter_matches(matches, 0)
  print(vim.treesitter.get_node_text(m:child(), 0))

  if true then
    return
  end

  for _, match in matches do
    for _, node in pairs(match) do
      if not node or not node:child(1) or not node:child(1):child() then
        -- print(vim.treesitter.get_node_text(node:child(1):child(), 0))
        goto continue
      end

      if vim.treesitter.get_node_text(node:child(1):child(), 0) == func then
        local def = ""
        for i = 0, node:child_count() - 2 do
          def = def..vim.treesitter.get_node_text(node:child(i), 0)
          if i < node:child_count() - 2 then
            def = def.." "
          end
        end
        -- Print the function name using node text
        return def:gsub("\n", "")
      end
      ::continue::
    end
  end

  return nil
end

return {
  -- function snippet
  s({ trig = [[fn\|main]], trigEngine = "vim" }, {
    d(1, function(_, snip)
      if snip.trigger == "main" then
        return sn(nil, {
          t({ "int", "main(int argc, char *argv[])" })
        })
      else
        return sn(nil, {
          c(1, {
            t(""),
            t("static "),
          }),
          c(2, {
            t("void"),
            t("char"),
            t("int"),
            t("short"),
            t("long"),
            t("double"),
            t("float"),
            i(nil, "myType"),
          }),
          t({ "", "" }),
          c(3, {
            t(""),
            t("*")
          }),
          i(4, "myFunc");
          t("("),
          i(5),
          t(")"),
        })
      end
    end, {}),
    t({ "", "{", "\t" }),
    i(0),
    t({ "", "}" })
  }),

  -- create decleration based on existing c function
  postfix(".d", {
    f(function(_, parent)
      local r = c_func(parent.snippet.env.POSTFIX_MATCH)
      if not r then
        return parent.snippet.env.POSTFIX_MATCH
      end
      local bidx, aidx = r:find(parent.snippet.env.POSTFIX_MATCH)

      return r:sub(1, bidx - 1)..
        parent.snippet.env.POSTFIX_MATCH..
        r:sub(aidx + 1)..";"
    end, {})
  })
}