//! Contains the [`Value`] and [`ValueInner`] containers into which all toml
//! contents can be deserialized into and either used directly or fed into
//! [`crate::Deserialize`] or your own constructs to deserialize into your own
//! types

use crate::{Error, ErrorKind, Span};
use std::{borrow::Cow, fmt};

/// A deserialized [`ValueInner`] with accompanying [`Span`] information for where
/// it was located in the toml document
pub struct Value<'de> {
    value: Option<ValueInner<'de>>,
    /// The location of the value in the toml document
    pub span: Span,
}

impl<'de> Value<'de> {
    /// Creates a new [`Value`] with an empty [`Span`]
    #[inline]
    pub fn new(value: ValueInner<'de>) -> Self {
        Self::with_span(value, Span::default())
    }

    /// Creates a new [`Value`] with the specified [`Span`]
    #[inline]
    pub fn with_span(value: ValueInner<'de>, span: Span) -> Self {
        Self {
            value: Some(value),
            span,
        }
    }

    /// Takes the inner [`ValueInner`]
    ///
    /// This panics if the inner value has already been taken.
    ///
    /// Typically paired with [`Self::set`]
    #[inline]
    pub fn take(&mut self) -> ValueInner<'de> {
        self.value.take().expect("the value has already been taken")
    }

    /// Sets the inner [`ValueInner`]
    ///
    /// This is typically done when the value is taken with [`Self::take`],
    /// processed, and returned
    #[inline]
    pub fn set(&mut self, value: ValueInner<'de>) {
        self.value = Some(value);
    }

    /// Returns true if the value is a table and is non-empty
    #[inline]
    pub fn has_keys(&self) -> bool {
        self.value.as_ref().map_or(false, |val| {
            if let ValueInner::Table(table) = val {
                !table.is_empty()
            } else {
                false
            }
        })
    }

    /// Returns true if the value is a table and has the specified key
    #[inline]
    pub fn has_key(&self, key: &str) -> bool {
        self.value.as_ref().map_or(false, |val| {
            if let ValueInner::Table(table) = val {
                table.contains_key(&key.into())
            } else {
                false
            }
        })
    }

    /// Takes the value as a string, returning an error with either a default
    /// or user supplied message
    #[inline]
    pub fn take_string(&mut self, msg: Option<&'static str>) -> Result<Cow<'de, str>, Error> {
        match self.take() {
            ValueInner::String(s) => Ok(s),
            other => Err(Error {
                kind: ErrorKind::Wanted {
                    expected: msg.unwrap_or("a string"),
                    found: other.type_str(),
                },
                span: self.span,
                line_info: None,
            }),
        }
    }

    /// Returns a borrowed string if this is a [`ValueInner::String`]
    #[inline]
    pub fn as_str(&self) -> Option<&str> {
        self.value.as_ref().and_then(|v| v.as_str())
    }

    /// Returns a borrowed table if this is a [`ValueInner::Table`]
    #[inline]
    pub fn as_table(&self) -> Option<&Table<'de>> {
        self.value.as_ref().and_then(|v| v.as_table())
    }

    /// Returns a borrowed array if this is a [`ValueInner::Array`]
    #[inline]
    pub fn as_array(&self) -> Option<&Array<'de>> {
        self.value.as_ref().and_then(|v| v.as_array())
    }

    /// Returns an `i64` if this is a [`ValueInner::Integer`]
    #[inline]
    pub fn as_integer(&self) -> Option<i64> {
        self.value.as_ref().and_then(|v| v.as_integer())
    }

    /// Returns an `f64` if this is a [`ValueInner::Float`]
    #[inline]
    pub fn as_float(&self) -> Option<f64> {
        self.value.as_ref().and_then(|v| v.as_float())
    }

    /// Returns a `bool` if this is a [`ValueInner::Boolean`]
    #[inline]
    pub fn as_bool(&self) -> Option<bool> {
        self.value.as_ref().and_then(|v| v.as_bool())
    }

    /// Uses JSON pointer-like syntax to lookup a specific [`Value`]
    ///
    /// The basic format is:
    ///
    /// - The path starts with `/`
    /// - Each segment is separated by a `/`
    /// - Each segment is either a key name, or an integer array index
    ///
    /// ```rust
    /// let data = "[x]\ny = ['z', 'zz']";
    /// let value = toml_span::parse(data).unwrap();
    /// assert_eq!(value.pointer("/x/y/1").unwrap().as_str().unwrap(), "zz");
    /// assert!(value.pointer("/a/b/c").is_none());
    /// ```
    ///
    /// Note that this is JSON pointer**-like** because `/` is not supported in
    /// key names because I don't see the point. If you want this it is easy to
    /// implement.
    pub fn pointer(&self, pointer: &'de str) -> Option<&Self> {
        if pointer.is_empty() {
            return Some(self);
        } else if !pointer.starts_with('/') {
            return None;
        }

        pointer
            .split('/')
            .skip(1)
            // Don't support / or ~ in key names unless someone actually opens
            // an issue about it
            //.map(|x| x.replace("~1", "/").replace("~0", "~"))
            .try_fold(self, |target, token| {
                (match &target.value {
                    Some(ValueInner::Table(tab)) => tab.get(&token.into()),
                    Some(ValueInner::Array(list)) => parse_index(token).and_then(|x| list.get(x)),
                    _ => None,
                })
                .filter(|v| v.value.is_some())
            })
    }

    /// The `mut` version of [`Self::pointer`]
    pub fn pointer_mut(&mut self, pointer: &'de str) -> Option<&mut Self> {
        if pointer.is_empty() {
            return Some(self);
        } else if !pointer.starts_with('/') {
            return None;
        }

        pointer
            .split('/')
            .skip(1)
            // Don't support / or ~ in key names unless someone actually opens
            // an issue about it
            //.map(|x| x.replace("~1", "/").replace("~0", "~"))
            .try_fold(self, |target, token| {
                (match &mut target.value {
                    Some(ValueInner::Table(tab)) => tab.get_mut(&token.into()),
                    Some(ValueInner::Array(list)) => {
                        parse_index(token).and_then(|x| list.get_mut(x))
                    }
                    _ => None,
                })
                .filter(|v| v.value.is_some())
            })
    }
}

fn parse_index(s: &str) -> Option<usize> {
    if s.starts_with('+') || (s.starts_with('0') && s.len() != 1) {
        return None;
    }
    s.parse().ok()
}

impl<'de> AsRef<ValueInner<'de>> for Value<'de> {
    fn as_ref(&self) -> &ValueInner<'de> {
        self.value
            .as_ref()
            .expect("the value has already been taken")
    }
}

impl<'de> fmt::Debug for Value<'de> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{:?}", self.value)
    }
}

/// A toml table key
#[derive(Clone)]
pub struct Key<'de> {
    /// The key itself, in most cases it will be borrowed, but may be owned
    /// if escape characters are present in the original source
    pub name: Cow<'de, str>,
    /// The span for the key in the original document
    pub span: Span,
}

impl<'de> From<&'de str> for Key<'de> {
    fn from(k: &'de str) -> Self {
        Self {
            name: Cow::Borrowed(k),
            span: Span::default(),
        }
    }
}

impl<'de> fmt::Debug for Key<'de> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.name)
    }
}

impl<'de> Ord for Key<'de> {
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.name.cmp(&other.name)
    }
}

impl<'de> PartialOrd for Key<'de> {
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        Some(self.cmp(other))
    }
}

impl<'de> PartialEq for Key<'de> {
    fn eq(&self, other: &Self) -> bool {
        self.name.eq(&other.name)
    }
}

impl<'de> Eq for Key<'de> {}

/// A toml table, always represented as a sorted map.
///
/// The original key ordering can be obtained by ordering the keys by their span
pub type Table<'de> = std::collections::BTreeMap<Key<'de>, Value<'de>>;
/// A toml array
pub type Array<'de> = Vec<Value<'de>>;

/// The core value types that toml can deserialize to
///
/// Note that this library does not support datetime values that are part of the
/// toml spec since I have no need of them, but could be added
#[derive(Debug)]
pub enum ValueInner<'de> {
    /// A string.
    ///
    /// This will be borrowed from the original toml source unless it contains
    /// escape characters
    String(Cow<'de, str>),
    /// An integer
    Integer(i64),
    /// A float
    Float(f64),
    /// A boolean
    Boolean(bool),
    /// An array
    Array(Array<'de>),
    /// A table
    Table(Table<'de>),
}

impl<'de> ValueInner<'de> {
    /// Gets the type of the value as a string
    pub fn type_str(&self) -> &'static str {
        match self {
            Self::String(..) => "string",
            Self::Integer(..) => "integer",
            Self::Float(..) => "float",
            Self::Boolean(..) => "boolean",
            Self::Array(..) => "array",
            Self::Table(..) => "table",
        }
    }

    /// Returns a borrowed string if this is a [`Self::String`]
    #[inline]
    pub fn as_str(&self) -> Option<&str> {
        if let Self::String(s) = self {
            Some(s.as_ref())
        } else {
            None
        }
    }

    /// Returns a borrowed table if this is a [`Self::Table`]
    #[inline]
    pub fn as_table(&self) -> Option<&Table<'de>> {
        if let ValueInner::Table(t) = self {
            Some(t)
        } else {
            None
        }
    }

    /// Returns a borrowed array if this is a [`Self::Array`]
    #[inline]
    pub fn as_array(&self) -> Option<&Array<'de>> {
        if let ValueInner::Array(a) = self {
            Some(a)
        } else {
            None
        }
    }

    /// Returns an `i64` if this is a [`Self::Integer`]
    #[inline]
    pub fn as_integer(&self) -> Option<i64> {
        if let ValueInner::Integer(i) = self {
            Some(*i)
        } else {
            None
        }
    }

    /// Returns an `f64` if this is a [`Self::Float`]
    #[inline]
    pub fn as_float(&self) -> Option<f64> {
        if let ValueInner::Float(f) = self {
            Some(*f)
        } else {
            None
        }
    }

    /// Returns a `bool` if this is a [`Self::Boolean`]
    #[inline]
    pub fn as_bool(&self) -> Option<bool> {
        if let ValueInner::Boolean(b) = self {
            Some(*b)
        } else {
            None
        }
    }
}
