const std = @import("std");

pub fn create(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) *std.Build.Step.Compile {
    const lib = b.addStaticLibrary(.{
        .name = "evdev",
        .target = target,
        .optimize = optimize,
    });

    lib.linkLibC();
    lib.linkSystemLibrary("rt");

    const evdev_dep = b.dependency("libevdev", .{
        .target = target,
        .optimize = optimize,
    });

    lib.addConfigHeader(b.addConfigHeader(.{ .include_path = "config.h" }, .{
        ._GNU_SOURCE = 1,
    }));

    const event_names_h = b: {
        const run = b.addRunArtifact(b.addExecutable(.{
            .name = "capture_out",
            .root_source_file = b.path("libs/evdev/capture_out.zig"),
            .target = b.graph.host,
        }));
        const out = run.addOutputFileArg("libevdev/event-names.h");
        run.addFileArg(evdev_dep.path("libevdev/make-event-names.py"));
        run.addFileInput(evdev_dep.path("libevdev/libevdev.h"));
        const os = switch (target.result.os.tag) {
            .linux => "linux",
            .freebsd => "freebsd",
            else => @panic("Unsupported OS"),
        };
        run.addFileArg(evdev_dep.path(b.fmt("include/linux/{s}/input.h", .{os})));
        run.addFileArg(evdev_dep.path(b.fmt("include/linux/{s}/input-event-codes.h", .{os})));
        break :b out;
    };

    lib.addIncludePath(event_names_h.dirname());
    lib.addIncludePath(evdev_dep.path("."));
    lib.addIncludePath(evdev_dep.path("include"));

    const flags = &[_][]const u8{
        // c_std=gnu99
        "-std=gnu99",
        // warning_level=2
        "-Wall",
        "-Wextra",
        // cflags
        "-Wno-unused-parameter",
        "-fvisibility=hidden",
        "-Wmissing-prototypes",
        "-Wstrict-prototypes",
        // disable UB sanitizer, which is enabled by default by Zig
        "-fno-sanitize=undefined",
        "-D_FORTIFY_SOURCE=0", // really really bad (!!!) but too lazy to backport __poll_chk (sys/poll.h) to kindle glibc
    };
    lib.addCSourceFiles(.{
        .root = evdev_dep.path("."),
        .flags = flags,
        .files = &.{
            "libevdev/libevdev-uinput.c",
            "libevdev/libevdev.c",
            "libevdev/libevdev-names.c",
        },
    });

    lib.installHeader(evdev_dep.path("libevdev/libevdev.h"), "libevdev/libevdev.h");
    lib.installHeader(evdev_dep.path("libevdev/libevdev-uinput.h"), "libevdev/libevdev-uinput.h");

    return lib;
}
