// Auto-generated token definitions from schemas
// DO NOT EDIT - Generated by build.rs at compile time

use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum AbugidaToken {
    // Vowels (independent)
{{#each abugida_vowels}}
    {{this}},
{{/each}}

    // Vowel signs (dependent)
{{#each abugida_vowel_signs}}
    {{this}},
{{/each}}

    // Consonants
{{#each abugida_consonants}}
    {{this}},
{{/each}}

    // Marks
{{#each abugida_marks}}
    {{this}},
{{/each}}

    // Special characters
{{#each abugida_special}}
    {{this}},
{{/each}}

    // Vedic marks
{{#each abugida_vedic}}
    {{this}},
{{/each}}

    // Digits
{{#each abugida_digits}}
    {{this}},
{{/each}}

    // Unknown token for preserving unmapped characters
    Unknown(String),
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum AlphabetToken {
    // Vowels
{{#each alphabet_vowels}}
    {{this}},
{{/each}}

    // Consonants
{{#each alphabet_consonants}}
    {{this}},
{{/each}}

    // Marks
{{#each alphabet_marks}}
    {{this}},
{{/each}}

    // Special characters
{{#each alphabet_special}}
    {{this}},
{{/each}}

    // Vedic marks
{{#each alphabet_vedic}}
    {{this}},
{{/each}}

    // Digits
{{#each alphabet_digits}}
    {{this}},
{{/each}}

    // Unknown token for preserving unmapped characters
    Unknown(String),
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum HubToken {
    Abugida(AbugidaToken),
    Alphabet(AlphabetToken),
}

impl HubToken {
    pub fn is_unknown(&self) -> bool {
        matches!(
            self,
            HubToken::Abugida(AbugidaToken::Unknown(_)) | HubToken::Alphabet(AlphabetToken::Unknown(_))
        )
    }

    pub fn as_unknown_string(&self) -> Option<&str> {
        #[allow(unreachable_patterns)]
        match self {
            HubToken::Abugida(AbugidaToken::Unknown(s)) | HubToken::Alphabet(AlphabetToken::Unknown(s)) => Some(s),
            _ => None,
        }
    }
    
    pub fn is_consonant(&self) -> bool {
        match self {
            HubToken::Abugida(token) => matches!(token,
{{#each abugida_consonants}}
                AbugidaToken::{{this}}{{#unless @last}} |{{/unless}}
{{/each}}
            ),
            HubToken::Alphabet(token) => matches!(token,
{{#each alphabet_consonants}}
                AlphabetToken::{{this}}{{#unless @last}} |{{/unless}}
{{/each}}
            ),
        }
    }
    
    pub fn is_vowel(&self) -> bool {
        match self {
            HubToken::Abugida(token) => matches!(token,
{{#each abugida_vowels}}
                AbugidaToken::{{this}}{{#unless @last}} |{{/unless}}
{{/each}}
            ),
            HubToken::Alphabet(token) => matches!(token,
{{#each alphabet_vowels}}
                AlphabetToken::{{this}}{{#unless @last}} |{{/unless}}
{{/each}}
            ),
        }
    }
    
    pub fn is_vowel_sign(&self) -> bool {
        match self {
            HubToken::Abugida(token) => matches!(token,
{{#each abugida_vowel_signs}}
                AbugidaToken::{{this}}{{#unless @last}} |{{/unless}}
{{/each}}
            ),
            HubToken::Alphabet(_) => false, // Alphabet tokens don't have vowel signs
        }
    }
    
    pub fn is_virama(&self) -> bool {
        matches!(self, HubToken::Abugida(AbugidaToken::MarkVirama))
    }
    
    pub fn is_vedic_accent(&self) -> bool {
        match self {
            HubToken::Abugida(token) => token.is_vedic_accent(),
            HubToken::Alphabet(token) => token.is_vedic_accent(),
        }
    }
    
    pub fn is_yogavaha(&self) -> bool {
        match self {
            HubToken::Abugida(token) => token.is_yogavaha(),
            HubToken::Alphabet(token) => token.is_yogavaha(),
        }
    }
}

// Token relationship mappings
impl AbugidaToken {
    // Convert vowel to corresponding vowel sign
    pub fn vowel_to_sign(&self) -> Option<Self> {
        #[allow(unreachable_patterns)]
        match self {
{{#each vowel_to_sign_mappings}}
            AbugidaToken::{{this.vowel}} => Some(AbugidaToken::{{this.sign}}),
{{/each}}
            _ => None,
        }
    }
    
    // Convert vowel sign to corresponding vowel
    pub fn sign_to_vowel(&self) -> Option<Self> {
        #[allow(unreachable_patterns)]
        match self {
{{#each vowel_to_sign_mappings}}
            AbugidaToken::{{this.sign}} => Some(AbugidaToken::{{this.vowel}}),
{{/each}}
            _ => None,
        }
    }
    
    // Convert to corresponding alphabet token
    pub fn to_alphabet(&self) -> Option<AlphabetToken> {
        #[allow(unreachable_patterns)]
        match self {
{{#each abugida_to_alphabet_mappings}}
            AbugidaToken::{{this.from}} => Some(AlphabetToken::{{this.to}}),
{{/each}}
            AbugidaToken::Unknown(s) => Some(AlphabetToken::Unknown(s.clone())),
            _ => None,
        }
    }
    
    // Type categorization helpers
    pub fn is_consonant(&self) -> bool {
        matches!(self,
{{#each abugida_consonants}}
            AbugidaToken::{{this}}{{#unless @last}} |{{/unless}}
{{/each}}
        )
    }
    
    pub fn is_vowel(&self) -> bool {
        matches!(self,
{{#each abugida_vowels}}
            AbugidaToken::{{this}}{{#unless @last}} |{{/unless}}
{{/each}}
        )
    }
    
    pub fn is_vowel_sign(&self) -> bool {
        matches!(self,
{{#each abugida_vowel_signs}}
            AbugidaToken::{{this}}{{#unless @last}} |{{/unless}}
{{/each}}
        )
    }
    
    pub fn is_virama(&self) -> bool {
        matches!(self, AbugidaToken::MarkVirama)
    }
    
    pub fn is_mark(&self) -> bool {
        matches!(self,
{{#each abugida_marks}}
            AbugidaToken::{{this}}{{#unless @last}} |{{/unless}}
{{/each}}
{{#if abugida_vedic}}
{{#each abugida_vedic}}
            | AbugidaToken::{{this}}
{{/each}}
{{/if}}
        )
    }
    
    pub fn is_vedic_accent(&self) -> bool {
        matches!(self,
{{#each abugida_vedic}}
            AbugidaToken::{{this}}{{#unless @last}} |{{/unless}}
{{/each}}
        )
    }
    
    pub fn is_yogavaha(&self) -> bool {
        matches!(self,
{{#each abugida_marks}}
            AbugidaToken::{{this}}{{#unless @last}} |{{/unless}}
{{/each}}
        )
    }
}

impl AlphabetToken {
    // Convert to corresponding abugida token
    pub fn to_abugida(&self) -> Option<AbugidaToken> {
        #[allow(unreachable_patterns)]
        match self {
{{#each alphabet_to_abugida_mappings}}
            AlphabetToken::{{this.from}} => Some(AbugidaToken::{{this.to}}),
{{/each}}
            AlphabetToken::Unknown(s) => Some(AbugidaToken::Unknown(s.clone())),
            _ => None,
        }
    }
    
    // Type categorization helpers
    pub fn is_consonant(&self) -> bool {
        matches!(self,
{{#each alphabet_consonants}}
            AlphabetToken::{{this}}{{#unless @last}} |{{/unless}}
{{/each}}
        )
    }
    
    pub fn is_vowel(&self) -> bool {
        matches!(self,
{{#each alphabet_vowels}}
            AlphabetToken::{{this}}{{#unless @last}} |{{/unless}}
{{/each}}
        )
    }
    
    pub fn is_mark(&self) -> bool {
        matches!(self,
{{#each alphabet_marks}}
            AlphabetToken::{{this}}{{#unless @last}} |{{/unless}}
{{/each}}
{{#if alphabet_vedic}}
{{#each alphabet_vedic}}
            | AlphabetToken::{{this}}
{{/each}}
{{/if}}
        )
    }
    
    pub fn is_vedic_accent(&self) -> bool {
        matches!(self,
{{#each alphabet_vedic}}
            AlphabetToken::{{this}}{{#unless @last}} |{{/unless}}
{{/each}}
        )
    }
    
    pub fn is_yogavaha(&self) -> bool {
        matches!(self,
{{#each alphabet_marks}}
            AlphabetToken::{{this}}{{#unless @last}} |{{/unless}}
{{/each}}
        )
    }
}

pub type HubTokenSequence = Vec<HubToken>;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum HubFormat {
    Abugida,
    Alphabet,
}

// Implement Display and FromStr for AbugidaToken
impl std::fmt::Display for AbugidaToken {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
{{#each abugida_vowels}}
            AbugidaToken::{{this}} => write!(f, "{{this}}"),
{{/each}}
{{#each abugida_vowel_signs}}
            AbugidaToken::{{this}} => write!(f, "{{this}}"),
{{/each}}
{{#each abugida_consonants}}
            AbugidaToken::{{this}} => write!(f, "{{this}}"),
{{/each}}
{{#each abugida_marks}}
            AbugidaToken::{{this}} => write!(f, "{{this}}"),
{{/each}}
{{#each abugida_special}}
            AbugidaToken::{{this}} => write!(f, "{{this}}"),
{{/each}}
{{#each abugida_vedic}}
            AbugidaToken::{{this}} => write!(f, "{{this}}"),
{{/each}}
{{#each abugida_digits}}
            AbugidaToken::{{this}} => write!(f, "{{this}}"),
{{/each}}
            AbugidaToken::Unknown(c) => write!(f, "Unknown({})", c),
        }
    }
}

impl std::str::FromStr for AbugidaToken {
    type Err = String;
    
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
{{#each abugida_vowels}}
            "{{this}}" => Ok(AbugidaToken::{{this}}),
{{/each}}
{{#each abugida_vowel_signs}}
            "{{this}}" => Ok(AbugidaToken::{{this}}),
{{/each}}
{{#each abugida_consonants}}
            "{{this}}" => Ok(AbugidaToken::{{this}}),
{{/each}}
{{#each abugida_marks}}
            "{{this}}" => Ok(AbugidaToken::{{this}}),
{{/each}}
{{#each abugida_special}}
            "{{this}}" => Ok(AbugidaToken::{{this}}),
{{/each}}
{{#each abugida_vedic}}
            "{{this}}" => Ok(AbugidaToken::{{this}}),
{{/each}}
{{#each abugida_digits}}
            "{{this}}" => Ok(AbugidaToken::{{this}}),
{{/each}}
            _ if s.starts_with("Unknown(") && s.ends_with(')') => {
                let inner = &s[8..s.len()-1];
                Ok(AbugidaToken::Unknown(inner.to_string()))
            }
            _ => Err(format!("Unknown AbugidaToken: {}", s))
        }
    }
}

// Implement Display and FromStr for AlphabetToken  
impl std::fmt::Display for AlphabetToken {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
{{#each alphabet_vowels}}
            AlphabetToken::{{this}} => write!(f, "{{this}}"),
{{/each}}
{{#each alphabet_consonants}}
            AlphabetToken::{{this}} => write!(f, "{{this}}"),
{{/each}}
{{#each alphabet_marks}}
            AlphabetToken::{{this}} => write!(f, "{{this}}"),
{{/each}}
{{#each alphabet_special}}
            AlphabetToken::{{this}} => write!(f, "{{this}}"),
{{/each}}
{{#each alphabet_vedic}}
            AlphabetToken::{{this}} => write!(f, "{{this}}"),
{{/each}}
{{#each alphabet_digits}}
            AlphabetToken::{{this}} => write!(f, "{{this}}"),
{{/each}}
            AlphabetToken::Unknown(c) => write!(f, "Unknown({})", c),
        }
    }
}

impl std::str::FromStr for AlphabetToken {
    type Err = String;
    
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
{{#each alphabet_vowels}}
            "{{this}}" => Ok(AlphabetToken::{{this}}),
{{/each}}
{{#each alphabet_consonants}}
            "{{this}}" => Ok(AlphabetToken::{{this}}),
{{/each}}
{{#each alphabet_marks}}
            "{{this}}" => Ok(AlphabetToken::{{this}}),
{{/each}}
{{#each alphabet_special}}
            "{{this}}" => Ok(AlphabetToken::{{this}}),
{{/each}}
{{#each alphabet_vedic}}
            "{{this}}" => Ok(AlphabetToken::{{this}}),
{{/each}}
{{#each alphabet_digits}}
            "{{this}}" => Ok(AlphabetToken::{{this}}),
{{/each}}
            _ if s.starts_with("Unknown(") && s.ends_with(')') => {
                let inner = &s[8..s.len()-1];
                Ok(AlphabetToken::Unknown(inner.to_string()))
            }
            _ => Err(format!("Unknown AlphabetToken: {}", s))
        }
    }
}