// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

extern crate alloc;

use crate::crubit_cc_std_internal::conversion_function_helpers;
use alloc::string::String;
use alloc::vec::Vec;
use bridge_rust::{CrubitAbi, Decoder, Encoder};
use core::clone::Clone;
use core::cmp::Eq;
use core::cmp::PartialEq;
use core::ffi::c_void;
use core::mem::{ManuallyDrop, MaybeUninit};
use core::ops::Deref;
use core::ptr::NonNull;

/// An owned C++ string. The pointer is guaranteed to be a non-null C++
/// allocated pointer to std::string.
///
/// We make sure that conversion between `string` and `std::string` is O(1), but
/// conversion between `string` and other types like `&str` or `String` can be
/// O(n).
// TODO: Make it mutable?.
// TODO: add a depedency on `crubit_annotate` to use that directly rather than doc attributes.
#[doc = "CRUBIT_ANNOTATE: cpp_type=std::string"]
#[doc = "CRUBIT_ANNOTATE: include_path=<string>"]
#[doc = "CRUBIT_ANNOTATE: cpp_to_rust_converter=cpp_string_to_rust_string"]
#[doc = "CRUBIT_ANNOTATE: rust_to_cpp_converter=rust_string_to_cpp_string"]
#[allow(non_snake_case)]
#[repr(C)]
pub struct string {
    owned_cpp_string: NonNull<c_void>,
}

impl string {
    pub fn as_slice(&self) -> &[u8] {
        self.as_ref()
    }

    /// Returns a `*const c_void` pointing to the underlying C++
    /// `std::string` object.
    ///
    /// The caller must ensure that the `string` outlives the pointer.
    ///
    /// This method guarantees that for the purpose of the aliasing
    /// model, this method does not materialize a reference to the
    /// underlying data the string owns, and thus the returned
    /// pointer will remain valid when mixed with other calls to
    /// `as_void_ptr` and `as_mut_void_ptr`.
    pub fn as_void_ptr(&self) -> *const c_void {
        self.owned_cpp_string.as_ptr() as *const _
    }

    /// Returns a `*mut c_void` pointing to the underlying C++
    /// `std::string` object.
    ///
    /// The caller must ensure that the `string` outlives the pointer.
    ///
    /// This method guarantees that for the purpose of the aliasing
    /// model, this method does not materialize a reference to the
    /// underlying data the string owns, and thus the returned
    /// pointer will remain valid when mixed with other calls to
    /// `as_void_ptr` and `as_mut_void_ptr`.
    ///
    /// However, note that writing to the pointer will invalidate references to
    /// the underlying data. For example, the behavior is undefined if the
    /// underlying string is mutated through this pointer during the lifetime
    /// of a slice as returned by `as_slice`.
    pub fn as_mut_void_ptr(&mut self) -> *mut c_void {
        self.owned_cpp_string.as_ptr()
    }

    /// Returns an object that implements `Display` for safely printing paths that may contain
    /// non-Unicode data. This may perform lossy conversion, depending on the underlying data.
    pub fn display(&self) -> Display<'_> {
        Display(self.as_slice())
    }
}

impl PartialEq for string {
    fn eq(&self, other: &Self) -> bool {
        unsafe {
            // SAFETY: `owned_cpp_string` is guaranteed to be a non-null C++ allocated
            // pointer to std::string.
            conversion_function_helpers::StringEqual(
                self.owned_cpp_string.as_ptr(),
                other.owned_cpp_string.as_ptr(),
            )
        }
    }
}

impl Eq for string {}

impl Default for string {
    fn default() -> Self {
        "".into()
    }
}

impl Clone for string {
    fn clone(&self) -> Self {
        // SAFETY: `owned_cpp_string` is guaranteed to be a non-null C++ allocated
        // pointer to std::string.
        let raw_string = unsafe {
            conversion_function_helpers::StringCopyOwnedPtr(self.owned_cpp_string.as_ptr())
        };
        if let Some(ptr) = NonNull::new(raw_string) {
            Self { owned_cpp_string: ptr }
        } else {
            panic!("Failed to copy string");
        }
    }
}

impl Drop for string {
    fn drop(&mut self) {
        unsafe {
            // SAFETY: `owned_cpp_string` is guaranteed to be a non-null C++ allocated
            // pointer to std::string.
            conversion_function_helpers::StringDelete(self.owned_cpp_string.as_ptr());
        }
    }
}

impl From<String> for string {
    fn from(s: String) -> Self {
        s.as_bytes().into()
    }
}

impl From<&String> for string {
    fn from(s: &String) -> Self {
        s.as_bytes().into()
    }
}

impl From<&Vec<u8>> for string {
    fn from(s: &Vec<u8>) -> Self {
        s.as_slice().into()
    }
}

impl From<&str> for string {
    fn from(s: &str) -> Self {
        s.as_bytes().into()
    }
}

impl From<&[u8]> for string {
    fn from(s: &[u8]) -> Self {
        // SAFETY: Rust slice returns a valid pointer to a buffer of bytes.
        let raw_string = unsafe {
            conversion_function_helpers::StringCreateFromBuffer(s.as_ptr() as _, s.len())
        };
        if let Some(ptr) = NonNull::new(raw_string) {
            Self { owned_cpp_string: ptr }
        } else {
            panic!("Failed to create string");
        }
    }
}

impl Deref for string {
    type Target = [u8];
    fn deref(&self) -> &Self::Target {
        let ptr = self.owned_cpp_string.as_ptr();
        // SAFETY:
        //
        // * `owned_cpp_string` is guaranteed to be a non-null C++ allocated pointer to
        //   std::string so `ptr` is non-null.
        // * `StringGetData` returns the pointer of the C++ `std::string::data()`, which
        //   is guaranteed to be non-null and point to a continuous memory region. Every
        //   byte in [ptr, ptr + len)) is intialized. (See https://en.cppreference.com/w/cpp/string/basic_string/data)
        // * The data is guaranteed to be not mutated because we don't ever mutate
        //   data() except when accessed via &mut self, which is blocked by Rust borrow
        //   checker.
        // * `len` is guaranteed to be less than `isize::MAX` because C++
        //   implementations guarantee in practice that the object won't go past the end
        //   of the address space.
        unsafe {
            let len = conversion_function_helpers::StringGetSize(ptr);
            core::slice::from_raw_parts(conversion_function_helpers::StringGetData(ptr) as _, len)
        }
    }
}

impl core::convert::AsRef<[u8]> for string {
    fn as_ref(&self) -> &[u8] {
        &*self
    }
}

impl core::fmt::Debug for string {
    // TODO(b/351976622): Make a pretty Debug like std::string(b"\xffhello\xde") or
    // similar.
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "cc_std::string({:?})", self.as_slice())
    }
}

impl core::fmt::Display for string {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        self.display().fmt(f)
    }
}

// Allow converting a cc_std::std::string reference to a "real" C++ string pointer.

type StringSymbol = forward_declare::symbol!(
    "std :: basic_string < char , std :: char_traits < char >, std :: allocator < char >>"
);

impl<'a, Crate> forward_declare::CppCast<*const forward_declare::Incomplete<StringSymbol, Crate>>
    for &'a string
{
    fn cpp_cast(self) -> *const forward_declare::Incomplete<StringSymbol, Crate> {
        self.owned_cpp_string.as_ptr() as *const _ as *const _
    }
}

impl<'a, Crate> forward_declare::CppCast<*mut forward_declare::Incomplete<StringSymbol, Crate>>
    for &'a mut string
{
    fn cpp_cast(self) -> *mut forward_declare::Incomplete<StringSymbol, Crate> {
        self.owned_cpp_string.as_ptr() as *mut _
    }
}

/// Helper struct for safely printing C++ string data with `format!` and `{}`.
///
/// A string from C++ might contain non-Unicode data. This struct implements the Display trait in a
/// way that mitigates that. It is created by the display method on `string`. This may perform lossy
/// conversion, depending on the underlying data.
pub struct Display<'a>(&'a [u8]);

impl<'a> core::fmt::Display for Display<'a> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        use core::fmt::Write;
        for chunk in self.0.utf8_chunks() {
            f.write_str(chunk.valid())?;
            if !chunk.invalid().is_empty() {
                f.write_char(core::char::REPLACEMENT_CHARACTER)?;
            }
        }
        Ok(())
    }
}

/// The Crubit ABI for C++ `std::string`. It is specified as one pointer.
///
/// This pointer should point to a heap allocated `std::string` object, where the pointer is the
/// owner of the allocation. Alternatively, the pointer can be null if and only if the allocation
/// failed, in which case it's okay to panic.
pub struct BoxedCppStringAbi;

unsafe impl CrubitAbi for BoxedCppStringAbi {
    type Value = string;

    const SIZE: usize = core::mem::size_of::<*mut c_void>();

    fn encode(value: Self::Value, encoder: &mut Encoder) {
        encoder.encode_transmute(ManuallyDrop::new(value).as_mut_void_ptr());
    }

    unsafe fn decode(decoder: &mut Decoder) -> Self::Value {
        // SAFETY: the caller guarantees that the buffer contains an allocated or null pointer to a
        // C++ `std::string` object.
        let ptr: *mut c_void = unsafe { decoder.decode_transmute() };

        Self::Value {
            owned_cpp_string: NonNull::new(ptr).expect("Boxing a std::string shouldn't fail"),
        }
    }
}

// Void pointer converters are needed for cc_bindings_from_rs.

#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust_string_to_cpp_string(input: *const c_void, output: *mut c_void) {
    // SAFETY:
    // * `input` is a valid `string`.
    // * `input.owned_cpp_string` is guaranteed to be a non-null C++ allocated
    //   pointer to std::string.
    // * `output` is a valid C++ `std::string`.
    unsafe {
        let input = &*(input as *const string);
        conversion_function_helpers::StringCreateInPlace(output, input.owned_cpp_string.as_ptr());
    }
}

#[unsafe(no_mangle)]
pub unsafe extern "C" fn cpp_string_to_rust_string(input: *mut c_void, output: *mut c_void) {
    // SAFETY: `input` is a valid `std::string` so it can be safely moved.
    let owned_cpp_string = unsafe { conversion_function_helpers::StringMoveOwnedPtr(input) };
    if let Some(ptr) = NonNull::new(owned_cpp_string) {
        let output = &mut *(output as *mut MaybeUninit<string>);
        output.as_mut_ptr().write(string { owned_cpp_string: ptr });
    } else {
        panic!("Failed to create owned string");
    }
}
