extern crate proc_macro;

mod enum_hack;

use proc_macro2::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
use proc_macro_hack::proc_macro_hack;
use quote::{quote, ToTokens};
use std::iter::FromIterator;
use syn::parse::{Error, Parse, ParseStream, Parser, Result};
use syn::{parenthesized, parse_macro_input, Lit, LitStr, Token};

#[proc_macro]
pub fn item(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let input = parse_macro_input!(input as PasteInput);
    proc_macro::TokenStream::from(input.expanded)
}

#[proc_macro]
pub fn item_with_macros(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let input = parse_macro_input!(input as PasteInput);
    proc_macro::TokenStream::from(enum_hack::wrap(input.expanded))
}

#[proc_macro_hack]
pub fn expr(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let input = parse_macro_input!(input as PasteInput);
    let output = input.expanded;
    proc_macro::TokenStream::from(quote!({ #output }))
}

#[doc(hidden)]
#[proc_macro_derive(EnumHack)]
pub fn enum_hack(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    enum_hack::extract(input)
}

struct PasteInput {
    expanded: TokenStream,
}

impl Parse for PasteInput {
    fn parse(input: ParseStream) -> Result<Self> {
        let mut expanded = TokenStream::new();
        while !input.is_empty() {
            match input.parse()? {
                TokenTree::Group(group) => {
                    let delimiter = group.delimiter();
                    let content = group.stream();
                    let span = group.span();
                    if delimiter == Delimiter::Bracket && is_paste_operation(&content) {
                        let segments = parse_bracket_as_segments.parse2(content)?;
                        let pasted = paste_segments(span, &segments)?;
                        pasted.to_tokens(&mut expanded);
                    } else if delimiter == Delimiter::None && is_single_ident(&content) {
                        content.to_tokens(&mut expanded);
                    } else {
                        let nested = PasteInput::parse.parse2(content)?;
                        let mut group = Group::new(delimiter, nested.expanded);
                        group.set_span(span);
                        group.to_tokens(&mut expanded);
                    }
                }
                other => other.to_tokens(&mut expanded),
            }
        }
        Ok(PasteInput { expanded })
    }
}

fn is_paste_operation(input: &TokenStream) -> bool {
    let input = input.clone();
    parse_bracket_as_segments.parse2(input).is_ok()
}

fn is_single_ident(input: &TokenStream) -> bool {
    let mut has_ident = false;
    for tt in input.clone() {
        match tt {
            TokenTree::Ident(_) if !has_ident => has_ident = true,
            _ => return false,
        }
    }
    has_ident
}

enum Segment {
    String(String),
    Apostrophe(Span),
    Env(LitStr),
    Modifier(Token![:], Ident),
}

fn parse_bracket_as_segments(input: ParseStream) -> Result<Vec<Segment>> {
    input.parse::<Token![<]>()?;

    let segments = parse_segments(input)?;

    input.parse::<Token![>]>()?;
    if !input.is_empty() {
        return Err(input.error("invalid input"));
    }
    Ok(segments)
}

fn parse_segments(input: ParseStream) -> Result<Vec<Segment>> {
    let mut segments = Vec::new();
    while !(input.is_empty() || input.peek(Token![>])) {
        match input.parse()? {
            TokenTree::Ident(ident) => {
                let mut fragment = ident.to_string();
                if fragment.starts_with("r#") {
                    fragment = fragment.split_off(2);
                }
                if fragment == "env" && input.peek(Token![!]) {
                    input.parse::<Token![!]>()?;
                    let arg;
                    parenthesized!(arg in input);
                    let var: LitStr = arg.parse()?;
                    segments.push(Segment::Env(var));
                } else {
                    segments.push(Segment::String(fragment));
                }
            }
            TokenTree::Literal(lit) => {
                let value = match syn::parse_str(&lit.to_string())? {
                    Lit::Str(string) => string.value().replace('-', "_"),
                    Lit::Int(_) => lit.to_string(),
                    _ => return Err(Error::new(lit.span(), "unsupported literal")),
                };
                segments.push(Segment::String(value));
            }
            TokenTree::Punct(punct) => match punct.as_char() {
                '_' => segments.push(Segment::String("_".to_string())),
                '\'' => segments.push(Segment::Apostrophe(punct.span())),
                ':' => segments.push(Segment::Modifier(Token![:](punct.span()), input.parse()?)),
                _ => return Err(Error::new(punct.span(), "unexpected punct")),
            },
            TokenTree::Group(group) => {
                if group.delimiter() == Delimiter::None {
                    let nested = parse_segments.parse2(group.stream())?;
                    segments.extend(nested);
                } else {
                    return Err(Error::new(group.span(), "unexpected token"));
                }
            }
        }
    }
    Ok(segments)
}

fn paste_segments(span: Span, segments: &[Segment]) -> Result<TokenStream> {
    let mut evaluated = Vec::new();
    let mut is_lifetime = false;

    for segment in segments {
        match segment {
            Segment::String(segment) => {
                evaluated.push(segment.clone());
            }
            Segment::Apostrophe(span) => {
                if is_lifetime {
                    return Err(Error::new(*span, "unexpected lifetime"));
                }
                is_lifetime = true;
            }
            Segment::Env(var) => {
                let resolved = match std::env::var(var.value()) {
                    Ok(resolved) => resolved,
                    Err(_) => {
                        return Err(Error::new(var.span(), "no such env var"));
                    }
                };
                let resolved = resolved.replace('-', "_");
                evaluated.push(resolved);
            }
            Segment::Modifier(colon, ident) => {
                let span = quote!(#colon #ident);
                let last = match evaluated.pop() {
                    Some(last) => last,
                    None => return Err(Error::new_spanned(span, "unexpected modifier")),
                };
                if ident == "lower" {
                    evaluated.push(last.to_lowercase());
                } else if ident == "upper" {
                    evaluated.push(last.to_uppercase());
                } else if ident == "snake" {
                    let mut acc = String::new();
                    let mut prev = '_';
                    for ch in last.chars() {
                        if ch.is_uppercase() && prev != '_' {
                            acc.push('_');
                        }
                        acc.push(ch);
                        prev = ch;
                    }
                    evaluated.push(acc.to_lowercase());
                } else if ident == "camel" {
                    let mut acc = String::new();
                    let mut prev = '_';
                    for ch in last.chars() {
                        if ch != '_' {
                            if prev == '_' {
                                for chu in ch.to_uppercase() {
                                    acc.push(chu);
                                }
                            } else if prev.is_uppercase() {
                                for chl in ch.to_lowercase() {
                                    acc.push(chl);
                                }
                            } else {
                                acc.push(ch);
                            }
                        }
                        prev = ch;
                    }
                    evaluated.push(acc);
                } else {
                    return Err(Error::new_spanned(span, "unsupported modifier"));
                }
            }
        }
    }

    let pasted = evaluated.into_iter().collect::<String>();
    let ident = TokenTree::Ident(Ident::new(&pasted, span));
    let tokens = if is_lifetime {
        let apostrophe = TokenTree::Punct(Punct::new('\'', Spacing::Joint));
        vec![apostrophe, ident]
    } else {
        vec![ident]
    };
    Ok(TokenStream::from_iter(tokens))
}
