# Generic Flex/Yacc Generation Functions
# This file provides reusable functions for generating C++ files from Flex/Bison sources

# Function to generate Flex lexer files
# Usage: generate_flex_lexer(OUTPUT_VAR INPUT_FILE [PREFIX] [HEADER_DEPENDENCY])
# OUTPUT_VAR: Variable name to store the output file path
# INPUT_FILE: Path to the .ll input file
# PREFIX: Optional prefix for the generated files (defaults to basename of input file)
# HEADER_DEPENDENCY: Optional header file that the lexer depends on (e.g., from Bison)
function(generate_flex_lexer OUTPUT_VAR INPUT_FILE)
    get_filename_component(INPUT_BASENAME ${INPUT_FILE} NAME_WE)

    if(ARGC GREATER 2)
        set(PREFIX ${ARGV2})
    else()
        set(PREFIX ${INPUT_BASENAME})
    endif()

    set(LEX_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}.cc)
    set(LEX_HEADER ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}.hh)

    # Set up dependencies
    set(DEPENDENCIES ${INPUT_FILE})
    if(ARGC GREATER 3)
        list(APPEND DEPENDENCIES ${ARGV3})
    endif()

    add_custom_command(
        OUTPUT ${LEX_OUTPUT}
        DEPENDS ${DEPENDENCIES}
        COMMAND ${FLEX_EXECUTABLE} --header-file=${LEX_HEADER} -o ${LEX_OUTPUT} ${INPUT_FILE}
        COMMENT "Generating ${PREFIX}.cc from ${INPUT_FILE}"
    )

    set(${OUTPUT_VAR} ${LEX_OUTPUT} PARENT_SCOPE)
endfunction()

# Function to generate Bison parser files
# Usage: generate_bison_parser(OUTPUT_VAR HEADER_VAR INPUT_FILE [PREFIX])
# OUTPUT_VAR: Variable name to store the output .cc file path
# HEADER_VAR: Variable name to store the output .hh file path
# INPUT_FILE: Path to the .yy input file
# PREFIX: Optional prefix for the generated files (defaults to basename of input file)
function(generate_bison_parser OUTPUT_VAR HEADER_VAR INPUT_FILE)
    get_filename_component(INPUT_BASENAME ${INPUT_FILE} NAME_WE)

    if(ARGC GREATER 3)
        set(PREFIX ${ARGV3})
    else()
        set(PREFIX ${INPUT_BASENAME})
    endif()

    set(YACC_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}.cc)
    set(YACC_HEADER ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}.hh)

    add_custom_command(
        OUTPUT ${YACC_OUTPUT} ${YACC_HEADER}
        DEPENDS ${INPUT_FILE}
        COMMAND ${BISON_EXECUTABLE} -p ${PREFIX} --header=${YACC_HEADER} -o ${YACC_OUTPUT} ${INPUT_FILE}
        COMMENT "Generating ${PREFIX}.cc and ${PREFIX}.hh from ${INPUT_FILE}"
    )

    set(${OUTPUT_VAR} ${YACC_OUTPUT} PARENT_SCOPE)
    set(${HEADER_VAR} ${YACC_HEADER} PARENT_SCOPE)
endfunction()

# Generate device attachment parser files using the generic functions
# Generate Bison parser first (creates the header file)
generate_bison_parser(YACC_OUTPUT YACC_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/deviceManager/deviceAttachmentPipeSpecp.yy deviceAttachmentPipeSpecp)

# Generate Flex lexer with dependency on Bison header
generate_flex_lexer(LEX_OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/deviceManager/deviceAttachmentPipeSpecl.ll deviceAttachmentPipeSpecl ${YACC_HEADER})
