use crate::syntax::namespace::Namespace;
use crate::syntax::CppName;
use proc_macro2::{Ident, TokenStream};
use quote::ToTokens;
use std::fmt::{self, Display, Write};

// A mangled symbol consisting of segments separated by '$'.
// For example: cxxbridge05$string$new
pub struct Symbol(String);

impl Display for Symbol {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        Display::fmt(&self.0, formatter)
    }
}

impl ToTokens for Symbol {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        ToTokens::to_tokens(&self.0, tokens);
    }
}

impl Symbol {
    fn push(&mut self, segment: &dyn Display) {
        let len_before = self.0.len();
        if !self.0.is_empty() {
            self.0.push('$');
        }
        self.0.write_fmt(format_args!("{}", segment)).unwrap();
        assert!(self.0.len() > len_before);
    }

    pub fn from_idents<'a, T: Iterator<Item = &'a Ident>>(it: T) -> Self {
        let mut symbol = Symbol(String::new());
        for segment in it {
            segment.write(&mut symbol);
        }
        assert!(!symbol.0.is_empty());
        symbol
    }

    /// For example, for taking a symbol and then making a new symbol
    /// for a vec of that symbol.
    pub fn prefix_with(&self, prefix: &str) -> Symbol {
        Symbol(format!("{}{}", prefix, self.to_string()))
    }
}

pub trait Segment {
    fn write(&self, symbol: &mut Symbol);
}

impl Segment for str {
    fn write(&self, symbol: &mut Symbol) {
        symbol.push(&self);
    }
}
impl Segment for usize {
    fn write(&self, symbol: &mut Symbol) {
        symbol.push(&self);
    }
}
impl Segment for Ident {
    fn write(&self, symbol: &mut Symbol) {
        symbol.push(&self);
    }
}
impl Segment for Symbol {
    fn write(&self, symbol: &mut Symbol) {
        symbol.push(&self);
    }
}

impl Segment for Namespace {
    fn write(&self, symbol: &mut Symbol) {
        for segment in self {
            symbol.push(segment);
        }
    }
}

impl Segment for CppName {
    fn write(&self, symbol: &mut Symbol) {
        self.namespace.write(symbol);
        self.ident.write(symbol);
    }
}

impl<T> Segment for &'_ T
where
    T: ?Sized + Segment + Display,
{
    fn write(&self, symbol: &mut Symbol) {
        (**self).write(symbol);
    }
}

pub fn join(segments: &[&dyn Segment]) -> Symbol {
    let mut symbol = Symbol(String::new());
    for segment in segments {
        segment.write(&mut symbol);
    }
    assert!(!symbol.0.is_empty());
    symbol
}
