// TextFSM Grammar Rules
WHITESPACE = _{ " " | "\t" }
COMMENT = _{ "#" ~ (!NEWLINE ~ ANY)* ~ NEWLINE }
NEWLINE = _{ "\r\n" | "\n" | "\r" }

file = _{ SOI ~ value_definitions? ~ state_definitions ~ EOI }

// Value Definitions Section
value_definitions = { value_definition+ ~ NEWLINE* }
value_definition = { "Value" ~ options? ~ identifier ~ regex_pattern ~ NEWLINE }
options = @{ option ~ ("," ~ option)* }
option = @{ "Required" | "List" | "Filldown" | "Fillup" | "Key" }
identifier = @{ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_")* }
regex_pattern = @{ "(" ~ inner_pattern ~ ")" }
inner_pattern = @{ (nested_parens | !("(" | ")") ~ ANY)* }
nested_parens = @{ "(" ~ inner_pattern ~ ")" }

// State Definitions Section
state_definitions = { state_definition+ }
state_definition = { state_header ~ NEWLINE ~ rules? ~ NEWLINE* }
state_header = { state_name }

// states in the wild do have numeric starts
// state_name = @{ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_")* }
state_name = @{ ( !"." ~ (ASCII_ALPHANUMERIC | "_"))+ }

// Rules
// rules = { (rule ~ NEWLINE)+ }
rules = { rule ~ (NEWLINE+ ~ rule)* ~ NEWLINE* }
rule = ${ indentation? ~ rule_match ~ rule_transition? }
indentation = _{ " "+ }
rule_match = { "^" ~ (!(" -> " | NEWLINE) ~ ANY)* }
rule_transition = _{ " -> " ~ WHITESPACE* ~ transition_action }

transition_action = ${ (line_rec_action ~ (WHITESPACE+ ~ next_state)? ) | next_state }
// hide line_rec_action - transition_action is atomic, so no whitespace handling here!
line_rec_action = _{ err_state | line_action ~ ( "." ~ record_action)? | record_action }
line_action = !{ "Next" | "Continue" }
record_action = !{ "NoRecord" | "Record" | "Clearall" | "Clear" }
next_state = !{ state_name }
err_state = !{ "Error" ~ err_msg? }
err_msg = @{ ("\"" ~ (!"\"" ~ ANY)* ~ "\"") | (!(WHITESPACE | NEWLINE) ~ ANY)* }
space = _{ " " }

// Record fields (for future expansion)
record_fields = { record_field+ }
record_field = { field_name? ~ field_value }
field_name = { identifier ~ "=" }
field_value = { "${" ~ identifier ~ "}" | "." | regex_pattern }
