local M = {}

---@class Porcelain
---@field author string
---@field author_email string
---@field author_time number
---@field author_tz string
---@field committer string
---@field committer_mail string
---@field committer_time number
---@field committer_tz string
---@field filename string
---@field hash string
---@field previous string|nil
---@field summary string
---@field content string
---@field original_line number

---Parses raw porcelain data (string[]) into an array of tables for each line containing the commit data
---@param blame_porcelain string[]
---@return Porcelain[]
M.parse_porcelain = function(blame_porcelain)
    local all_lines = {}
    for _, entry in ipairs(blame_porcelain) do
        local ident = entry:match("^%S+")
        if not ident then
            all_lines[#all_lines].content = entry
        elseif #ident == 40 then
            table.insert(all_lines, { hash = ident, original_line = tonumber(entry:match("^%S+ (%d+)")) })
        else
            ident = ident:gsub("-", "_")

            local info = string.sub(entry, #ident + 2, -1)
            if ident == "author_time" or ident == "committer_time" then
                all_lines[#all_lines][ident] = tonumber(info)
            else
                all_lines[#all_lines][ident] = info
            end
        end
    end
    return all_lines
end

---@class Hunk
---@field prev_line number
---@field prev_count number
---@field curr_line number
---@field curr_count number

---Parses git diff hunks to extract line number mappings
---@param diff string[]
---@return Hunk[]
M.parse_hunks = function(diff)
    local hunks = {}
    for _, line in ipairs(diff) do
        local prev_line, prev_lines, curr_line, curr_lines = line:match("^@@ %-(%d+),?(%d*) %+(%d+),?(%d*)")
        if prev_line then
            table.insert(hunks, {
                prev_line = tonumber(prev_line),
                prev_count = tonumber(prev_lines) or 1,
                curr_line = tonumber(curr_line),
                curr_count = tonumber(curr_lines) or 1
            })
        end
    end
    return hunks
end

return M
