const std = @import("std");

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

    const options = .{
        .enable_tracy = b.option(
            bool,
            "enable_tracy",
            "Enable Tracy profile markers",
        ) orelse false,
        .enable_fibers = b.option(
            bool,
            "enable_fibers",
            "Enable Tracy fiber support",
        ) orelse false,
        .on_demand = b.option(
            bool,
            "on_demand",
            "Build tracy with TRACY_ON_DEMAND",
        ) orelse false,
        .callstack = b.option(
            u32,
            "callstack",
            "If > 0, Builds tracy with TRACY_USE_CALLSTACK and sets TRACY_CALLSTACK to the depth provided.",
        ) orelse 0,
        .shared = b.option(
            bool,
            "shared",
            "Build as shared library",
        ) orelse false,
    };

    const options_step = b.addOptions();
    inline for (std.meta.fields(@TypeOf(options))) |field| {
        options_step.addOption(field.type, field.name, @field(options, field.name));
    }

    const options_module = options_step.createModule();

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

    const translate_c = b.addTranslateC(.{
        .root_source_file = tracy_src.path("public/tracy/TracyC.h"),
        .target = target,
        .optimize = optimize,
        .link_libc = true,
    });
    translate_c.addIncludePath(tracy_src.path("public/tracy"));
    translate_c.defineCMacro("TRACY_ENABLE", "");
    translate_c.defineCMacro("TRACY_IMPORTS", "");
    if (options.callstack > 0) {
        translate_c.defineCMacro("TRACY_USE_CALLSTACK", "");
        var callstack_buffer: [64]u8 = undefined;
        const callstack_str_len = std.fmt.printInt(&callstack_buffer, @as(u32, options.callstack), 10, .lower, .{});
        translate_c.defineCMacro("TRACY_CALLSTACK", callstack_buffer[0..callstack_str_len]);
    }

    const tracy_lib = b.addLibrary(.{
        .name = "tracy",
        .linkage = if (options.shared) .dynamic else .static,
        .root_module = b.createModule(.{
            .target = target,
            .optimize = optimize,
        }),
    });

    if (options.shared) tracy_lib.root_module.addCMacro("TRACY_EXPORTS", "");

    if (target.result.os.tag == .windows) tracy_lib.root_module.addCMacro("_WIN32_WINNT", "0x0601");

    if (options.enable_tracy) tracy_lib.root_module.addCMacro("TRACY_ENABLE", "");
    if (options.enable_fibers) tracy_lib.root_module.addCMacro("TRACY_FIBERS", "");
    if (options.on_demand) tracy_lib.root_module.addCMacro("TRACY_ON_DEMAND", "");

    tracy_lib.root_module.addIncludePath(tracy_src.path("public"));
    tracy_lib.root_module.addIncludePath(tracy_src.path("public/tracy"));
    tracy_lib.root_module.addIncludePath(tracy_src.path("public/common"));
    tracy_lib.root_module.addIncludePath(tracy_src.path("public/client"));
    tracy_lib.root_module.addCSourceFile(.{
        .file = tracy_src.path("public/TracyClient.cpp"),
        .flags = &.{
            "-fno-sanitize=undefined",
        },
    });

    tracy_lib.root_module.link_libc = true;
    if (target.result.abi != .msvc) {
        tracy_lib.root_module.link_libcpp = true;
    } else {
        tracy_lib.root_module.addCMacro("fileno", "_fileno");
    }

    // switch (target.result.os.tag) {
    //     .windows => {
    //         tracy_lib.root_module.linkSystemLibrary("ws2_32", .{});
    //         tracy_lib.root_module.linkSystemLibrary("dbghelp", .{});
    //         tracy_lib.root_module.linkSystemLibrary("secur32", .{}); // Provides GetUserNameExA
    //         tracy_lib.root_module.linkSystemLibrary("user32", .{});  // Often needed for other system calls
    //         tracy_lib.root_module.linkSystemLibrary("advapi32", .{});
    //     },
    //     // .macos => {
    //     //     if (b.lazyDependency("system_sdk", .{})) |system_sdk| {
    //     //         tracy_lib.root_module.addFrameworkPath(system_sdk.path("System/Library/Frameworks"));
    //     //     }
    //     // },
    //     else => {},
    // }

    b.installArtifact(tracy_lib);

    const tracy = b.addModule("tracy", .{
        .root_source_file = b.path("src/tracy.zig"),
        .imports = &.{
            .{ .name = "tracy_options", .module = options_module },
        },
    });
    tracy.addImport("c", translate_c.createModule());
    tracy.linkLibrary(tracy_lib);
}