use crate::ir::Ir;

pub mod swift;
pub mod ts;

/// Every language backend implements this. Adding a language is one impl + one
/// line in `emitter_for` — the core IR never changes. This is the seam where
/// contributors plug in new targets.
pub trait Emitter {
    fn emit(&self, ir: &Ir) -> String;
}

/// Per-target emitter options, threaded from `stele.toml`.
#[derive(Default, Clone, Copy)]
pub struct EmitOptions {
    pub callable: bool,
}

pub fn emitter_for(lang: &str, opts: EmitOptions) -> Option<Box<dyn Emitter>> {
    match lang {
        "typescript" | "ts" => Some(Box::new(ts::TsEmitter {
            callable: opts.callable,
        })),
        "swift" => Some(Box::new(swift::SwiftEmitter)),
        _ => None,
    }
}

/// Single-character encoding for a plural category, used to pack the baked
/// per-locale tables compactly into generated code.
pub fn cat_char(name: &str) -> char {
    match name {
        "zero" => 'z',
        "one" => '1',
        "two" => '2',
        "few" => 'f',
        "many" => 'm',
        _ => 'o',
    }
}
