const std = @import("std");

const Hook = *const fn (i32, i32) callconv(.c) i32;

pub fn main() !void {
    std.log.debug("setting up watches...", .{});

    var event: std.os.linux.inotify_event = undefined;
    const event_buf = std.mem.asBytes(&event);

    const fd: i32 = @intCast(std.os.linux.inotify_init1(std.os.linux.IN.NONBLOCK));
    defer _ = std.os.linux.close(fd);

    _ = std.os.linux.inotify_add_watch(fd, "./libroot.so", std.os.linux.IN.MODIFY);

    std.log.debug("loading dylib...", .{});

    var lib = try std.DynLib.open("./libroot.so");
    defer lib.close();

    var hook: Hook = lib.lookup(Hook, "hook").?;

    var polls = [_]std.os.linux.pollfd{
        .{ .fd = fd, .events = std.os.linux.POLL.IN, .revents = 0 },
    };

    while (true) {
        const eps = std.os.linux.poll(&polls, polls.len, 0);
        std.log.debug("eps: {d}", .{eps});
        if (eps > 0) {
            std.log.debug("event!", .{});
            while (std.os.linux.read(fd, event_buf.ptr, event_buf.len) > 0) {
                std.log.debug("consume.", .{});
            }
            std.log.debug("reloading.", .{});
            lib.close();
            lib = try std.DynLib.open("./libroot.so");
            hook = lib.lookup(Hook, "hook").?;
        }

        std.log.debug("update", .{});
        const res = hook(5, 7);
        std.log.debug("hook(5, 7) = {d}", .{res});

        std.time.sleep(std.time.ns_per_s);
    }
}
