//! `base64::` — standard and URL-safe Base64.
//!
//! Two encoders are exposed: standard alphabet with padding (`encode`/
//! `decode`) and URL-safe alphabet without padding (`encode_url`/
//! `decode_url`). Each encoder accepts both `String` and `Blob` inputs
//! as separate Rhai overloads; decoders always return `Blob` — the
//! caller knows whether the original bytes were textual.

use base64::engine::general_purpose::{STANDARD, URL_SAFE_NO_PAD};
use base64::Engine as _;
use rhai::{Blob, Engine as RhaiEngine, EvalAltResult, Module};

pub fn register(engine: &mut RhaiEngine) {
    let mut module = Module::new();

    module.set_native_fn("encode", |s: &str| -> Result<String, Box<EvalAltResult>> {
        Ok(STANDARD.encode(s.as_bytes()))
    });
    module.set_native_fn("encode", |b: Blob| -> Result<String, Box<EvalAltResult>> {
        Ok(STANDARD.encode(&b))
    });
    module.set_native_fn("decode", |s: &str| -> Result<Blob, Box<EvalAltResult>> {
        STANDARD
            .decode(s)
            .map_err(|e| format!("base64::decode: {e}").into())
    });

    module.set_native_fn(
        "encode_url",
        |s: &str| -> Result<String, Box<EvalAltResult>> {
            Ok(URL_SAFE_NO_PAD.encode(s.as_bytes()))
        },
    );
    module.set_native_fn(
        "encode_url",
        |b: Blob| -> Result<String, Box<EvalAltResult>> { Ok(URL_SAFE_NO_PAD.encode(&b)) },
    );
    module.set_native_fn(
        "decode_url",
        |s: &str| -> Result<Blob, Box<EvalAltResult>> {
            URL_SAFE_NO_PAD
                .decode(s)
                .map_err(|e| format!("base64::decode_url: {e}").into())
        },
    );

    engine.register_static_module("base64", module.into());
}
