/*-
 * Scram-rs - a SCRAM authentification authorization library
 * 
 * Copyright (C) 2021  Aleksandr Morozov
 * Copyright (C) 2025 Aleksandr Morozov
 * 
 * The syslog-rs crate can be redistributed and/or modified
 * under the terms of either of the following licenses:
 *
 *   1. the Mozilla Public License Version 2.0 (the “MPL”) OR
 *
 *   2. The MIT License (MIT)
 *                     
 *   3. EUROPEAN UNION PUBLIC LICENCE v. 1.2 EUPL © the European Union 2007, 2016
 */

 
#[cfg(feature = "std")]
use std::ffi::c_char;
#[cfg(not(feature = "std"))]
use core::ffi::c_char;

#[cfg(feature = "std")]
use std::ffi::CString;
#[cfg(not(feature = "std"))]
use alloc::ffi::CString;
use base64::{engine::general_purpose, Engine};

use super::common;

#[repr(C)]
pub struct CApiExpBase64
{
    pub base64: *mut c_char
}

#[unsafe(no_mangle)]
pub unsafe extern "C" 
fn capi_exp_base64_encode(input: *const u8, len: usize, out: *mut CApiExpBase64) -> i32
{
    if input.is_null() == true
    {
        return -1;
    }
    else if len == 0
    {
        return -2;
    }
    else if out.is_null() == true
    {
        return -3;
    }

    let inp_sl = 
        match common::carr_to_slice(input, len, "input or len is invalid")
        {
            Ok(r) => r,
            Err(_) => 
                return 1,
        };
    
    let s = CString::new( general_purpose::STANDARD.encode(inp_sl).as_bytes() ).unwrap();

    unsafe { out.as_mut().unwrap().base64 = s.into_raw() };

    return 0;
}

#[unsafe(no_mangle)]
pub unsafe extern "C" 
fn capi_exp_base64_free(base64: *mut CApiExpBase64)
{
    if base64.is_null() == true
    {
        return;
    }

    let sbase64 = unsafe {  base64.as_mut().unwrap() };

    drop(unsafe { CString::from_raw(sbase64.base64) });
}

