//! Serialization for client-server communication.

use std::any::Any;
use std::char;
use std::io::Write;
use std::num::NonZeroU32;
use std::ops::Bound;
use std::str;

pub(super) type Writer = super::buffer::Buffer<u8>;

pub(super) trait Encode<S>: Sized {
    fn encode(self, w: &mut Writer, s: &mut S);
}

pub(super) type Reader<'a> = &'a [u8];

pub(super) trait Decode<'a, 's, S>: Sized {
    fn decode(r: &mut Reader<'a>, s: &'s S) -> Self;
}

pub(super) trait DecodeMut<'a, 's, S>: Sized {
    fn decode(r: &mut Reader<'a>, s: &'s mut S) -> Self;
}

macro_rules! rpc_encode_decode {
    (le $ty:ty) => {
        impl<S> Encode<S> for $ty {
            fn encode(self, w: &mut Writer, _: &mut S) {
                w.write_all(&self.to_le_bytes()).unwrap();
            }
        }

        impl<S> DecodeMut<'_, '_, S> for $ty {
            fn decode(r: &mut Reader<'_>, _: &mut S) -> Self {
                const N: usize = ::std::mem::size_of::<$ty>();

                let mut bytes = [0; N];
                bytes.copy_from_slice(&r[..N]);
                *r = &r[N..];

                Self::from_le_bytes(bytes)
            }
        }
    };
    (struct $name:ident { $($field:ident),* $(,)? }) => {
        impl<S> Encode<S> for $name {
            fn encode(self, w: &mut Writer, s: &mut S) {
                $(self.$field.encode(w, s);)*
            }
        }

        impl<S> DecodeMut<'_, '_, S> for $name {
            fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
                $name {
                    $($field: DecodeMut::decode(r, s)),*
                }
            }
        }
    };
    (enum $name:ident $(<$($T:ident),+>)? { $($variant:ident $(($field:ident))*),* $(,)? }) => {
        impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)? {
            fn encode(self, w: &mut Writer, s: &mut S) {
                // HACK(eddyb): `Tag` enum duplicated between the
                // two impls as there's no other place to stash it.
                #[allow(non_upper_case_globals)]
                mod tag {
                    #[repr(u8)] enum Tag { $($variant),* }

                    $(pub const $variant: u8 = Tag::$variant as u8;)*
                }

                match self {
                    $($name::$variant $(($field))* => {
                        tag::$variant.encode(w, s);
                        $($field.encode(w, s);)*
                    })*
                }
            }
        }

        impl<S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S>
            for $name $(<$($T),+>)?
        {
            fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
                // HACK(eddyb): `Tag` enum duplicated between the
                // two impls as there's no other place to stash it.
                #[allow(non_upper_case_globals)]
                mod tag {
                    #[repr(u8)] enum Tag { $($variant),* }

                    $(pub const $variant: u8 = Tag::$variant as u8;)*
                }

                match u8::decode(r, s) {
                    $(tag::$variant => {
                        $(let $field = DecodeMut::decode(r, s);)*
                        $name::$variant $(($field))*
                    })*
                    _ => unreachable!(),
                }
            }
        }
    }
}

impl<S> Encode<S> for () {
    fn encode(self, _: &mut Writer, _: &mut S) {}
}

impl<S> DecodeMut<'_, '_, S> for () {
    fn decode(_: &mut Reader<'_>, _: &mut S) -> Self {}
}

impl<S> Encode<S> for u8 {
    fn encode(self, w: &mut Writer, _: &mut S) {
        w.write_all(&[self]).unwrap();
    }
}

impl<S> DecodeMut<'_, '_, S> for u8 {
    fn decode(r: &mut Reader<'_>, _: &mut S) -> Self {
        let x = r[0];
        *r = &r[1..];
        x
    }
}

rpc_encode_decode!(le u32);
rpc_encode_decode!(le usize);

impl<S> Encode<S> for bool {
    fn encode(self, w: &mut Writer, s: &mut S) {
        (self as u8).encode(w, s);
    }
}

impl<S> DecodeMut<'_, '_, S> for bool {
    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
        match u8::decode(r, s) {
            0 => false,
            1 => true,
            _ => unreachable!(),
        }
    }
}

impl<S> Encode<S> for char {
    fn encode(self, w: &mut Writer, s: &mut S) {
        (self as u32).encode(w, s);
    }
}

impl<S> DecodeMut<'_, '_, S> for char {
    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
        char::from_u32(u32::decode(r, s)).unwrap()
    }
}

impl<S> Encode<S> for NonZeroU32 {
    fn encode(self, w: &mut Writer, s: &mut S) {
        self.get().encode(w, s);
    }
}

impl<S> DecodeMut<'_, '_, S> for NonZeroU32 {
    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
        Self::new(u32::decode(r, s)).unwrap()
    }
}

impl<S, A: Encode<S>, B: Encode<S>> Encode<S> for (A, B) {
    fn encode(self, w: &mut Writer, s: &mut S) {
        self.0.encode(w, s);
        self.1.encode(w, s);
    }
}

impl<S, A: for<'s> DecodeMut<'a, 's, S>, B: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S>
    for (A, B)
{
    fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
        (DecodeMut::decode(r, s), DecodeMut::decode(r, s))
    }
}

rpc_encode_decode!(
    enum Bound<T> {
        Included(x),
        Excluded(x),
        Unbounded,
    }
);

rpc_encode_decode!(
    enum Option<T> {
        None,
        Some(x),
    }
);

rpc_encode_decode!(
    enum Result<T, E> {
        Ok(x),
        Err(e),
    }
);

impl<S> Encode<S> for &[u8] {
    fn encode(self, w: &mut Writer, s: &mut S) {
        self.len().encode(w, s);
        w.write_all(self).unwrap();
    }
}

impl<S> DecodeMut<'a, '_, S> for &'a [u8] {
    fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
        let len = usize::decode(r, s);
        let xs = &r[..len];
        *r = &r[len..];
        xs
    }
}

impl<S> Encode<S> for &str {
    fn encode(self, w: &mut Writer, s: &mut S) {
        self.as_bytes().encode(w, s);
    }
}

impl<S> DecodeMut<'a, '_, S> for &'a str {
    fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
        str::from_utf8(<&[u8]>::decode(r, s)).unwrap()
    }
}

impl<S> Encode<S> for String {
    fn encode(self, w: &mut Writer, s: &mut S) {
        self[..].encode(w, s);
    }
}

impl<S> DecodeMut<'_, '_, S> for String {
    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
        <&str>::decode(r, s).to_string()
    }
}

/// Simplied version of panic payloads, ignoring
/// types other than `&'static str` and `String`.
pub enum PanicMessage {
    StaticStr(&'static str),
    String(String),
    Unknown,
}

impl From<Box<dyn Any + Send>> for PanicMessage {
    fn from(payload: Box<dyn Any + Send + 'static>) -> Self {
        if let Some(s) = payload.downcast_ref::<&'static str>() {
            return PanicMessage::StaticStr(s);
        }
        if let Ok(s) = payload.downcast::<String>() {
            return PanicMessage::String(*s);
        }
        PanicMessage::Unknown
    }
}

impl Into<Box<dyn Any + Send>> for PanicMessage {
    fn into(self) -> Box<dyn Any + Send> {
        match self {
            PanicMessage::StaticStr(s) => Box::new(s),
            PanicMessage::String(s) => Box::new(s),
            PanicMessage::Unknown => {
                struct UnknownPanicMessage;
                Box::new(UnknownPanicMessage)
            }
        }
    }
}

impl PanicMessage {
    pub fn as_str(&self) -> Option<&str> {
        match self {
            PanicMessage::StaticStr(s) => Some(s),
            PanicMessage::String(s) => Some(s),
            PanicMessage::Unknown => None,
        }
    }
}

impl<S> Encode<S> for PanicMessage {
    fn encode(self, w: &mut Writer, s: &mut S) {
        self.as_str().encode(w, s);
    }
}

impl<S> DecodeMut<'_, '_, S> for PanicMessage {
    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
        match Option::<String>::decode(r, s) {
            Some(s) => PanicMessage::String(s),
            None => PanicMessage::Unknown,
        }
    }
}
