#!/usr/bin/env python3
import sys

def generate_inc(hooks):
    print("/* Generated file, do not edit directly */\n")

    #Emit include
    print("#include \"dpif-doca-tcpdump-hooks.h\"\n")

    # Emit string array
    print("const char *dpif_doca_tcpdump_hook_names[] = {")
    for enum, string, _ in hooks:
        print(f"    [DPIF_DOCA_TCPDUMP_HOOK_{enum}] = \"{string}\",")
    print("};\n")

def generate_h(hooks):
    print("/* Generated file, do not edit directly */\n")

    # Emit file header
    print("#ifndef DPIF_DOCA_TCPDUMP_HOOKS_H")
    print("#define DPIF_DOCA_TCPDUMP_HOOKS_H\n")

    # Emit enum
    print("enum dpif_doca_tcpdump_hook {")
    for i, (enum, _, _) in enumerate(hooks):
        comma = "," if i < len(hooks) - 1 else ""
        print(f"    DPIF_DOCA_TCPDUMP_HOOK_{enum}{comma}")
    print("};\n")

    # Emit file footer
    print("#endif /* dpif-doca-tcpdump-hooks.h */\n")

def generate_py(hooks):
    print('"""Generated file, do not edit directly"""')
    print("from enum import Enum\n")
    print("class DOCATcpdumpHook(str, Enum):")
    print('    """DOCA tcpdump hook types."""')

    # Enum members
    for enum, string, desc in hooks:
        print(f'    {enum} = "{string}"')

    print("\n    @property")
    print("    def description(self) -> str:")
    print("        return {")
    for enum, string, desc in hooks:
        print(f'            self.{enum}: "{desc}",')
    print("        }[self]\n")

    # from_string method
    print("    @classmethod")
    print("    def from_string(cls, hook_str: str) -> 'DOCATcpdumpHook':")
    print("        try:")
    print("            return cls(hook_str.lower())")
    print("        except ValueError:")
    print("            return cls.RX               # default\n")

    # verify_hook_exists method
    print("    @classmethod")
    print("    def verify_hook_exists(cls, hook_str: str) -> 'DOCATcpdumpHook':")
    print("        try:")
    print("            return cls(hook_str.lower())")
    print("        except ValueError:")
    print("            available = \", \".join(h.value for h in cls)")
    print("            raise ValueError(")
    print("                f\"Unknown hook '{hook_str}'. \"")
    print("                f\"Available hooks: {available}\"")
    print("            )")

def main():
    mode, defs = sys.argv[1], sys.argv[2]
    hooks = []
    with open(defs) as f:
        for line in f:
            if not line.strip() or line.strip().startswith("#"):
                continue
            enum, string, desc = line.strip().split(" ", 2)
            hooks.append((enum, string, desc.strip('"')))

    if mode == "--inc":
        generate_inc(hooks)
    elif mode == "--h":
        generate_h(hooks)
    elif mode == "--py":
        generate_py(hooks)
    else:
        sys.exit("Usage: dpif-doca-tcpdump-gen-hooks (--inc|--h|--py) dpif-doca-tcpdump-hooks")

if __name__ == "__main__":
    main()
