/*-
 * 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(not(feature = "std"))]
use crate::alloc::string::ToString;

#[cfg(not(feature = "std"))]
use alloc::string::String;

#[cfg(not(feature = "std"))]
use alloc::vec::Vec;

#[cfg(feature = "std")]
use std::{slice, ffi::{c_char, CStr}};
#[cfg(not(feature = "std"))]
use core::{slice, ffi::{c_char, CStr}};


use crate::{capi_scram_err, capi_scram_err_map, scram_error, scram_error_map, ScramErrorCode, ScramResult, ScramServerError};

use super::error::CApiScramResult;

#[inline]
pub(super) 
fn cstr_to_string<E: AsRef<str>>(ptr_char: *const c_char, err_desc: E) -> CApiScramResult<String>
{
    return
        unsafe
        {
            CStr::from_ptr(ptr_char)
                .to_str()
                .map_err(|e|
                    capi_scram_err_map!(ScramErrorCode::InternalError, ScramServerError::None, "{} UTF-8 err: {}", err_desc.as_ref(), e)
                )
                .map(|s| s.to_string())
        };
}

#[inline]
pub(super) 
fn carr_to_vec<E: AsRef<str>>(ptr: *const u8, ptr_len: usize, err_desc: E) -> CApiScramResult<Vec<u8>>
{
    return  
        if ptr.is_null() == false && ptr_len > 0
        {
            Ok( unsafe { slice::from_raw_parts(ptr, ptr_len) }.to_vec())
        }
        else if ptr.is_null() == true
        {
            capi_scram_err!(ScramErrorCode::InternalError, ScramServerError::None, "{}, array ptr is null", err_desc.as_ref())
        }
        else
        {
            capi_scram_err!(ScramErrorCode::InternalError, ScramServerError::None, "{} array len is zero", err_desc.as_ref())
        };
}


#[inline]
pub(super) 
fn carr_to_slice<'pt, E: AsRef<str>>(ptr: *const u8, ptr_len: usize, err_desc: E) -> CApiScramResult<&'pt [u8]>
{
    return  
        if ptr.is_null() == false && ptr_len > 0
        {
            Ok( unsafe { slice::from_raw_parts(ptr, ptr_len) })
        }
        else if ptr.is_null() == true
        {
            capi_scram_err!(ScramErrorCode::InternalError, ScramServerError::None, "{}, array ptr is null", err_desc.as_ref())
        }
        else
        {
            capi_scram_err!(ScramErrorCode::InternalError, ScramServerError::None, "{} array len is zero", err_desc.as_ref())
        };
}

#[inline]
pub(super) 
fn cstr_to_string_n<E: AsRef<str>>(ptr_char: *const c_char, err_desc: E) -> ScramResult<String>
{
    return
        unsafe
        {
            CStr::from_ptr(ptr_char)
                .to_str()
                .map_err(|e|
                    scram_error_map!(ScramErrorCode::InternalError, ScramServerError::None, "{} UTF-8 err: {}", err_desc.as_ref(), e)
                )
                .map(|s| s.to_string())
        };
}

#[inline]
pub(super) 
fn carr_to_slice_n<'pt, E: AsRef<str>>(ptr: *const u8, ptr_len: usize, err_desc: E) -> ScramResult<&'pt [u8]>
{
    return  
        if ptr.is_null() == false && ptr_len > 0
        {
            Ok( unsafe { slice::from_raw_parts(ptr, ptr_len) })
        }
        else if ptr.is_null() == true
        {
            scram_error!(ScramErrorCode::InternalError, ScramServerError::None, "{}, array ptr is null", err_desc.as_ref())
        }
        else
        {
            scram_error!(ScramErrorCode::InternalError, ScramServerError::None, "{} array len is zero", err_desc.as_ref())
        };
}


