const std = @import("std");

const c = @cImport({
    @cInclude("houdini.h");
});

pub fn escapeHtml(allocator: std.mem.Allocator, data: []const u8) !?[]const u8 {
    var buf: c.gh_buf = undefined;
    c.gh_buf_init(&buf, data.len);
    defer c.gh_buf_free(&buf);

    const res = c.houdini_escape_html(&buf, @ptrCast(data), data.len);
    if (res == 0) return null;

    const escaped = try allocator.alloc(u8, c.gh_buf_len(&buf));
    errdefer allocator.free(escaped);
    @memcpy(escaped, c.gh_buf_cstr(&buf)[0..escaped.len]);

    return escaped;
}

pub fn escapeUriComponent(allocator: std.mem.Allocator, data: []const u8) !?[]const u8 {
    var buf: c.gh_buf = undefined;
    c.gh_buf_init(&buf, data.len);
    defer c.gh_buf_free(&buf);

    const res = c.houdini_escape_uri_component(&buf, @ptrCast(data), data.len);
    if (res == 0) return null;

    const escaped = try allocator.alloc(u8, c.gh_buf_len(&buf));
    errdefer allocator.free(escaped);
    @memcpy(escaped, c.gh_buf_cstr(&buf)[0..escaped.len]);

    return escaped;
}

pub fn unescapeUriComponent(allocator: std.mem.Allocator, data: []const u8) !?[]const u8 {
    var buf: c.gh_buf = undefined;
    c.gh_buf_init(&buf, data.len);
    defer c.gh_buf_free(&buf);

    const res = c.houdini_unescape_uri_component(&buf, @ptrCast(data), data.len);
    if (res == 0) return null;

    const unescaped = try allocator.alloc(u8, c.gh_buf_len(&buf));
    errdefer allocator.free(unescaped);
    @memcpy(unescaped, c.gh_buf_cstr(&buf)[0..unescaped.len]);

    return unescaped;
}
