use crate::encode::{Encode, EncodeState};
use crate::raw_string::RawString;
use std::fmt::{self, Write};
use std::ops::{Deref, DerefMut, Range};
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct Decor {
    prefix: Option<RawString>,
    suffix: Option<RawString>,
}
impl Decor {
    pub fn new(prefix: impl Into<RawString>, suffix: impl Into<RawString>) -> Decor {
        Decor {
            prefix: Some(prefix.into()),
            suffix: Some(suffix.into()),
        }
    }
    pub fn set_prefix(&mut self, prefix: impl Into<RawString>) {
        self.prefix = Some(prefix.into());
    }
    pub fn set_suffix(&mut self, suffix: impl Into<RawString>) {
        self.suffix = Some(suffix.into());
    }
    pub fn prefix(&self) -> Option<&RawString> {
        self.prefix.as_ref()
    }
    pub fn suffix(&self) -> Option<&RawString> {
        self.suffix.as_ref()
    }
    pub fn clear(&mut self) {
        self.prefix = None;
        self.suffix = None;
    }
    pub(crate) fn encode_prefix(&self, buf: &mut EncodeState, default: &str) -> fmt::Result {
        if let Some(prefix) = self.prefix() {
            prefix.encode_with_default(buf, default)
        } else {
            buf.write_str(default)
        }
    }
    pub(crate) fn encode_suffix(&self, buf: &mut EncodeState, default: &str) -> fmt::Result {
        if let Some(suffix) = self.suffix() {
            suffix.encode_with_default(buf, default)
        } else {
            buf.write_str(default)
        }
    }
    pub(crate) fn despan(&mut self, input: &str) {
        if let Some(prefix) = &mut self.prefix {
            prefix.despan(input);
        }
        if let Some(suffix) = &mut self.suffix {
            suffix.despan(input);
        }
    }
}
impl<P, S> From<(P, S)> for Decor
where
    P: Into<RawString>,
    S: Into<RawString>,
{
    fn from((prefix, suffix): (P, S)) -> Self {
        Decor::new(prefix, suffix)
    }
}
pub trait Span {
    fn span(&self) -> Option<Range<usize>>;
}
impl<T> Span for Box<T>
where
    T: Span,
{
    fn span(&self) -> Option<Range<usize>> {
        (**self).span()
    }
}
pub(crate) trait SetSpan {
    fn set_span(&mut self, span: Range<usize>);
}
impl<T> SetSpan for Box<T>
where
    T: SetSpan,
{
    fn set_span(&mut self, span: Range<usize>) {
        (**self).set_span(span);
    }
}
pub trait Decorate {
    fn decor(&self) -> &Decor;
    fn decor_mut(&mut self) -> &mut Decor;
    fn decorate(&mut self, decor: impl Into<Decor>) {
        *self.decor_mut() = decor.into();
    }
    fn decorated(mut self, decor: impl Into<Decor>) -> Self
    where
        Self: Sized,
    {
        self.decorate(decor);
        self
    }
}
impl<T> Decorate for Box<T>
where
    T: Decorate,
{
    fn decor(&self) -> &Decor {
        (**self).decor()
    }
    fn decor_mut(&mut self) -> &mut Decor {
        (**self).decor_mut()
    }
}
#[derive(Debug, Clone, Eq)]
pub struct Spanned<T> {
    value: T,
    span: Option<Range<usize>>,
}
impl<T> Spanned<T> {
    pub fn new(value: T) -> Spanned<T> {
        Spanned { value, span: None }
    }
    pub fn into_value(self) -> T {
        self.value
    }
    pub fn value(&self) -> &T {
        &self.value
    }
    pub fn value_mut(&mut self) -> &mut T {
        &mut self.value
    }
    #[inline]
    pub fn value_into<U>(self) -> U
    where
        T: Into<U>,
    {
        self.value.into()
    }
}
impl<T> PartialEq for Spanned<T>
where
    T: PartialEq,
{
    fn eq(&self, other: &Self) -> bool {
        self.value == other.value
    }
}
impl<T> AsRef<T> for Spanned<T> {
    #[inline]
    fn as_ref(&self) -> &T {
        self.value()
    }
}
impl<T> AsMut<T> for Spanned<T> {
    #[inline]
    fn as_mut(&mut self) -> &mut T {
        self.value_mut()
    }
}
impl<T> Deref for Spanned<T> {
    type Target = T;
    #[inline]
    fn deref(&self) -> &T {
        self.as_ref()
    }
}
impl<T> DerefMut for Spanned<T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut T {
        self.as_mut()
    }
}
impl<T> From<T> for Spanned<T> {
    fn from(value: T) -> Self {
        Spanned::new(value)
    }
}
impl<T> Span for Spanned<T> {
    fn span(&self) -> Option<Range<usize>> {
        self.span.clone()
    }
}
impl<T> SetSpan for Spanned<T> {
    fn set_span(&mut self, span: Range<usize>) {
        self.span = Some(span);
    }
}
impl<T> fmt::Display for Spanned<T>
where
    T: Encode,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut state = EncodeState::new(f);
        self.encode(&mut state)
    }
}
#[derive(Debug, Clone, Eq)]
pub struct Decorated<T> {
    value: T,
    decor: Decor,
    span: Option<Range<usize>>,
}
impl<T> Decorated<T> {
    pub fn new(value: T) -> Decorated<T> {
        Decorated {
            value,
            decor: Decor::default(),
            span: None,
        }
    }
    pub fn into_value(self) -> T {
        self.value
    }
    pub fn value(&self) -> &T {
        &self.value
    }
    pub fn value_mut(&mut self) -> &mut T {
        &mut self.value
    }
    #[inline]
    pub fn value_into<U>(self) -> U
    where
        T: Into<U>,
    {
        self.value.into()
    }
}
impl<T> PartialEq for Decorated<T>
where
    T: PartialEq,
{
    fn eq(&self, other: &Self) -> bool {
        self.value == other.value
    }
}
impl<T> AsRef<T> for Decorated<T> {
    #[inline]
    fn as_ref(&self) -> &T {
        self.value()
    }
}
impl<T> AsMut<T> for Decorated<T> {
    #[inline]
    fn as_mut(&mut self) -> &mut T {
        self.value_mut()
    }
}
impl<T> Deref for Decorated<T> {
    type Target = T;
    #[inline]
    fn deref(&self) -> &T {
        self.as_ref()
    }
}
impl<T> DerefMut for Decorated<T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut T {
        self.as_mut()
    }
}
impl<T> From<T> for Decorated<T> {
    fn from(value: T) -> Self {
        Decorated::new(value)
    }
}
impl<T> Decorate for Decorated<T> {
    fn decor(&self) -> &Decor {
        &self.decor
    }
    fn decor_mut(&mut self) -> &mut Decor {
        &mut self.decor
    }
}
impl<T> Span for Decorated<T> {
    fn span(&self) -> Option<Range<usize>> {
        self.span.clone()
    }
}
impl<T> SetSpan for Decorated<T> {
    fn set_span(&mut self, span: Range<usize>) {
        self.span = Some(span);
    }
}
impl<T> fmt::Display for Decorated<T>
where
    T: Encode,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut state = EncodeState::new(f);
        self.encode(&mut state)
    }
}
#[derive(Debug, Clone, Eq)]
pub struct Formatted<T> {
    value: T,
    decor: Decor,
    repr: Option<RawString>,
    span: Option<Range<usize>>,
}
impl<T> Formatted<T>
where
    T: ToString,
{
    pub fn new(value: T) -> Formatted<T> {
        Formatted {
            value,
            decor: Decor::default(),
            repr: None,
            span: None,
        }
    }
    pub fn as_repr(&self) -> Option<&RawString> {
        self.repr.as_ref()
    }
    pub(crate) fn set_repr(&mut self, repr: impl Into<RawString>) {
        self.repr = Some(repr.into());
    }
    pub fn format(&mut self) {
        self.set_repr(self.value.to_string());
    }
}
impl<T> Formatted<T> {
    pub fn into_value(self) -> T {
        self.value
    }
    pub fn value(&self) -> &T {
        &self.value
    }
    pub fn value_mut(&mut self) -> &mut T {
        &mut self.value
    }
    #[inline]
    pub fn value_into<U>(self) -> U
    where
        T: Into<U>,
    {
        self.value.into()
    }
}
impl<T> PartialEq for Formatted<T>
where
    T: PartialEq,
{
    fn eq(&self, other: &Self) -> bool {
        self.value == other.value
    }
}
impl<T> AsRef<T> for Formatted<T> {
    #[inline]
    fn as_ref(&self) -> &T {
        self.value()
    }
}
impl<T> AsMut<T> for Formatted<T> {
    #[inline]
    fn as_mut(&mut self) -> &mut T {
        self.value_mut()
    }
}
impl<T> Deref for Formatted<T> {
    type Target = T;
    #[inline]
    fn deref(&self) -> &T {
        self.as_ref()
    }
}
impl<T> DerefMut for Formatted<T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut T {
        self.as_mut()
    }
}
impl<T> From<T> for Formatted<T>
where
    T: ToString,
{
    fn from(value: T) -> Self {
        Formatted::new(value)
    }
}
impl<T> Decorate for Formatted<T> {
    fn decor(&self) -> &Decor {
        &self.decor
    }
    fn decor_mut(&mut self) -> &mut Decor {
        &mut self.decor
    }
}
impl<T> Span for Formatted<T> {
    fn span(&self) -> Option<Range<usize>> {
        self.span.clone()
    }
}
impl<T> SetSpan for Formatted<T> {
    fn set_span(&mut self, span: Range<usize>) {
        self.span = Some(span);
    }
}
impl<T> fmt::Display for Formatted<T>
where
    T: Encode,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut state = EncodeState::new(f);
        self.encode(&mut state)
    }
}