const std = @import("std");
const builtin = std.builtin;
const zbs = std.build;

pub fn build(b: *zbs.Builder) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const strip = b.option(bool, "strip", "Omit debug information") orelse false;

    const cmph = b.addStaticLibrary(.{
        .name = "cmph",
        .target = target,
        .optimize = optimize,
    });
    cmph.linkLibC();
    cmph.addCSourceFiles(&.{
        "deps/cmph/src/bdz.c",
        "deps/cmph/src/bdz_ph.c",
        "deps/cmph/src/bmz8.c",
        "deps/cmph/src/bmz.c",
        "deps/cmph/src/brz.c",
        "deps/cmph/src/buffer_entry.c",
        "deps/cmph/src/buffer_manager.c",
        "deps/cmph/src/chd.c",
        "deps/cmph/src/chd_ph.c",
        "deps/cmph/src/chm.c",
        "deps/cmph/src/cmph.c",
        "deps/cmph/src/cmph_structs.c",
        "deps/cmph/src/compressed_rank.c",
        "deps/cmph/src/compressed_seq.c",
        "deps/cmph/src/fch_buckets.c",
        "deps/cmph/src/fch.c",
        "deps/cmph/src/graph.c",
        "deps/cmph/src/hash.c",
        "deps/cmph/src/jenkins_hash.c",
        "deps/cmph/src/linear_string_map.c",
        "deps/cmph/src/miller_rabin.c",
        "deps/cmph/src/select.c",
        "deps/cmph/src/vqueue.c",
    }, &.{
        "-W",
        "-Wno-unused-function",
        //"-DDEBUG",
    });
    cmph.strip = strip;
    cmph.want_lto = true;
    cmph.compress_debug_sections = .zlib;
    cmph.omit_frame_pointer = true;
    cmph.addIncludePath("deps/cmph/src");
    cmph.addConfigHeader(b.addConfigHeader(.{}, .{
        .HAVE_DLFCN_H = true,
        .HAVE_GETOPT_H = true,
        .HAVE_INTTYPES_H = true,
        .HAVE_MATH_H = true,
        .HAVE_MEMORY_H = true,
        .HAVE_STDINT_H = true,
        .HAVE_STDLIB_H = true,
        .HAVE_STRINGS_H = true,
        .HAVE_STRING_H = true,
        .HAVE_SYS_STAT_H = true,
        .HAVE_SYS_TYPES_H = true,
        .HAVE_UNISTD_H = true,
        .LT_OBJDIR = ".libs/",
        .PACKAGE = "cmph",
        .PACKAGE_BUGREPORT = "",
        .PACKAGE_NAME = "cmph",
        .PACKAGE_STRING = "cmph 2.0.2",
        .PACKAGE_TARNAME = "cmph",
        .PACKAGE_URL = "",
        .PACKAGE_VERSION = "2.0.2",
        .STDC_HEADERS = 1,
        .VERSION = "2.0.2",
    }));

    const bdz = b.addStaticLibrary(.{
        .name = "bdz",
        .target = target,
        .optimize = optimize,
    });
    bdz.linkLibC();
    bdz.addCSourceFiles(&.{
        "deps/bdz_read.c",
        "deps/cmph/src/hash.c",
        "deps/cmph/src/jenkins_hash.c",
    }, &.{
        "-W",
        "-Wno-unused-function",
        "-fvisibility=hidden",
        "-fpic",
        //"-DDEBUG",
    });
    bdz.omit_frame_pointer = true;
    bdz.addIncludePath("deps/cmph/src");
    bdz.addIncludePath("include/deps/cmph");
    bdz.want_lto = true;

    {
        const exe = b.addExecutable(.{
            .name = "turbonss-unix2db",
            .root_source_file = .{ .path = "src/turbonss-unix2db.zig" },
            .target = target,
            .optimize = optimize,
        });
        exe.compress_debug_sections = .zlib;
        exe.strip = strip;
        exe.want_lto = true;
        addCmphDeps(exe, cmph);
        b.installArtifact(exe);
    }

    {
        const exe = b.addExecutable(.{
            .name = "turbonss-analyze",
            .root_source_file = .{ .path = "src/turbonss-analyze.zig" },
            .target = target,
            .optimize = optimize,
        });
        exe.compress_debug_sections = .zlib;
        exe.strip = strip;
        exe.want_lto = true;
        b.installArtifact(exe);
    }

    {
        const exe = b.addExecutable(.{
            .name = "turbonss-makecorpus",
            .root_source_file = .{ .path = "src/turbonss-makecorpus.zig" },
            .target = target,
            .optimize = optimize,
        });
        exe.compress_debug_sections = .zlib;
        exe.strip = strip;
        exe.want_lto = true;
        b.installArtifact(exe);
    }

    {
        const exe = b.addExecutable(.{
            .name = "turbonss-getent",
            .root_source_file = .{ .path = "src/turbonss-getent.zig" },
            .target = target,
            .optimize = optimize,
        });
        exe.compress_debug_sections = .zlib;
        exe.strip = strip;
        exe.want_lto = true;
        exe.linkLibC();
        exe.linkLibrary(bdz);
        exe.addIncludePath("deps/cmph/src");
        b.installArtifact(exe);
    }

    {
        const so = b.addSharedLibrary(.{
            .name = "nss_turbo",
            .root_source_file = .{ .path = "src/libnss.zig" },
            .version = std.SemanticVersion{
                .major = 2,
                .minor = 0,
                .patch = 0,
            },
            .target = target,
            .optimize = optimize,
        });
        so.compress_debug_sections = .zlib;
        so.strip = strip;
        so.want_lto = true;
        so.linkLibC();
        so.linkLibrary(bdz);
        so.addIncludePath("deps/cmph/src");
        b.installArtifact(so);
    }

    {
        const src_test = b.addTest(.{
            .root_source_file = .{ .path = "src/test_all.zig" },
            .target = target,
            .optimize = optimize,
        });
        addCmphDeps(src_test, cmph);
        const test_step = b.step("test", "Run the tests");
        test_step.dependOn(&src_test.step);
    }
}

fn addCmphDeps(exe: *zbs.LibExeObjStep, cmph: *zbs.LibExeObjStep) void {
    exe.linkLibC();
    exe.linkLibrary(cmph);
    exe.addIncludePath("deps/cmph/src");
}
