const std = @import("std");

pub const Allocator = std.mem.Allocator;

pub const ManEntry = struct {
    name: []const u8,
    section: []const u8,
    description: []const u8,
    path: ?[]const u8 = null,

    pub fn getSectionMarker(self: ManEntry) []const u8 {
        if (self.section.len == 0) return "[?] Unknown";
        // Fast path for common sections
        return switch (self.section[0]) {
            '1' => "[*] Command",
            '2' => "[S] Syscall",
            '3' => blk: {
                // Check for specific 3xxx subsections (order matters - longer first)
                if (std.mem.startsWith(u8, self.section, "3ssl")) break :blk "[L] OpenSSL";
                if (std.mem.startsWith(u8, self.section, "3tcl")) break :blk "[L] Tcl API";
                if (std.mem.startsWith(u8, self.section, "3pm")) break :blk "[L] Perl";
                if (std.mem.startsWith(u8, self.section, "3p")) break :blk "[L] POSIX";
                if (std.mem.startsWith(u8, self.section, "3x")) break :blk "[L] X11/ncurses";
                break :blk "[L] C Library";
            },
            '4' => "[D] Device",
            '5' => "[F] Format",
            '6' => "[G] Game",
            '7' => "[M] Misc",
            '8' => "[A] Admin",
            '9' => "[K] Kernel",
            else => "[?] Unknown",
        };
    }

    pub fn matchesSection(self: ManEntry, target_sections: ?[]const []const u8) bool {
        if (target_sections == null) return true;
        for (target_sections.?) |section| {
            if (self.section.len == 0) continue;
            if (std.mem.eql(u8, self.section, section)) return true;
            if (section.len == 1 and std.mem.startsWith(u8, self.section, section)) return true;
        }
        return false;
    }
};

// Use modern ArrayList instead of custom implementation
pub const ManEntryList = std.ArrayList(ManEntry);

pub const SearchConfig = struct {
    keyword: []const u8,
    target_sections: ?[]const []const u8,
    show_paths: bool,
    verbose: bool,
};

// ============================================================================
// TESTS
// ============================================================================

test "ManEntry.getSectionMarker - commands" {
    const entry = ManEntry{
        .name = "ls",
        .section = "1",
        .description = "list directory contents",
        .path = null,
    };
    const marker = entry.getSectionMarker();
    try std.testing.expectEqualStrings("[*] Command", marker);
}

test "ManEntry.getSectionMarker - syscalls" {
    const entry = ManEntry{
        .name = "open",
        .section = "2",
        .description = "open file",
        .path = null,
    };
    const marker = entry.getSectionMarker();
    try std.testing.expectEqualStrings("[S] Syscall", marker);
}

test "ManEntry.getSectionMarker - C library" {
    const entry = ManEntry{
        .name = "printf",
        .section = "3",
        .description = "format and print data",
        .path = null,
    };
    const marker = entry.getSectionMarker();
    try std.testing.expectEqualStrings("[L] C Library", marker);
}

test "ManEntry.getSectionMarker - OpenSSL" {
    const entry = ManEntry{
        .name = "SSL_new",
        .section = "3ssl",
        .description = "create SSL structure",
        .path = null,
    };
    const marker = entry.getSectionMarker();
    try std.testing.expectEqualStrings("[L] OpenSSL", marker);
}

test "ManEntry.getSectionMarker - POSIX" {
    const entry = ManEntry{
        .name = "pthread_create",
        .section = "3p",
        .description = "create thread",
        .path = null,
    };
    const marker = entry.getSectionMarker();
    try std.testing.expectEqualStrings("[L] POSIX", marker);
}

test "ManEntry.getSectionMarker - kernel" {
    const entry = ManEntry{
        .name = "kmalloc",
        .section = "9",
        .description = "kernel memory alloc",
        .path = null,
    };
    const marker = entry.getSectionMarker();
    try std.testing.expectEqualStrings("[K] Kernel", marker);
}

test "ManEntry.getSectionMarker - unknown" {
    const entry = ManEntry{
        .name = "unknown",
        .section = "0",
        .description = "invalid section",
        .path = null,
    };
    const marker = entry.getSectionMarker();
    try std.testing.expectEqualStrings("[?] Unknown", marker);
}

test "ManEntry.matchesSection - no target" {
    const entry = ManEntry{
        .name = "ls",
        .section = "1",
        .description = "list",
        .path = null,
    };
    try std.testing.expect(entry.matchesSection(null));
}

test "ManEntry.matchesSection - exact match" {
    const entry = ManEntry{
        .name = "ls",
        .section = "1",
        .description = "list",
        .path = null,
    };
    const targets = &[_][]const u8{"1"};
    try std.testing.expect(entry.matchesSection(targets));
}

test "ManEntry.matchesSection - no match" {
    const entry = ManEntry{
        .name = "ls",
        .section = "1",
        .description = "list",
        .path = null,
    };
    const targets = &[_][]const u8{"3"};
    try std.testing.expect(!entry.matchesSection(targets));
}
