// SPDX-License-Identifier: GPL-2.0

use proc_macro::{Delimiter, Group, Ident, Spacing, Span, TokenTree};

fn concat_helper(tokens: &[TokenTree]) -> Vec<(String, Span)> {
    let mut tokens = tokens.iter();
    let mut segments = Vec::new();
    let mut span = None;
    loop {
        match tokens.next() {
            None => break,
            Some(TokenTree::Literal(lit)) => {
                // Allow us to concat string literals by stripping quotes
                let mut value = lit.to_string();
                if value.starts_with('"') && value.ends_with('"') {
                    value.remove(0);
                    value.pop();
                }
                segments.push((value, lit.span()));
            }
            Some(TokenTree::Ident(ident)) => {
                let mut value = ident.to_string();
                if value.starts_with("r#") {
                    value.replace_range(0..2, "");
                }
                segments.push((value, ident.span()));
            }
            Some(TokenTree::Punct(p)) if p.as_char() == ':' => {
                let Some(TokenTree::Ident(ident)) = tokens.next() else {
                    panic!("expected identifier as modifier");
                };

                let (mut value, sp) = segments.pop().expect("expected identifier before modifier");
                match ident.to_string().as_str() {
                    // Set the overall span of concatenated token as current span
                    "span" => {
                        assert!(
                            span.is_none(),
                            "span modifier should only appear at most once"
                        );
                        span = Some(sp);
                    }
                    "lower" => value = value.to_lowercase(),
                    "upper" => value = value.to_uppercase(),
                    v => panic!("unknown modifier `{v}`"),
                };
                segments.push((value, sp));
            }
            Some(TokenTree::Group(group)) if group.delimiter() == Delimiter::None => {
                let tokens = group.stream().into_iter().collect::<Vec<TokenTree>>();
                segments.append(&mut concat_helper(tokens.as_slice()));
            }
            token => panic!("unexpected token in paste segments: {token:?}"),
        };
    }

    segments
}

fn concat(tokens: &[TokenTree], group_span: Span) -> TokenTree {
    let segments = concat_helper(tokens);
    let pasted: String = segments.into_iter().map(|x| x.0).collect();
    TokenTree::Ident(Ident::new(&pasted, group_span))
}

pub(crate) fn expand(tokens: &mut Vec<TokenTree>) {
    for token in tokens.iter_mut() {
        if let TokenTree::Group(group) = token {
            let delimiter = group.delimiter();
            let span = group.span();
            let mut stream: Vec<_> = group.stream().into_iter().collect();
            // Find groups that looks like `[< A B C D >]`
            if delimiter == Delimiter::Bracket
                && stream.len() >= 3
                && matches!(&stream[0], TokenTree::Punct(p) if p.as_char() == '<')
                && matches!(&stream[stream.len() - 1], TokenTree::Punct(p) if p.as_char() == '>')
            {
                // Replace the group with concatenated token
                *token = concat(&stream[1..stream.len() - 1], span);
            } else {
                // Recursively expand tokens inside the group
                expand(&mut stream);
                let mut group = Group::new(delimiter, stream.into_iter().collect());
                group.set_span(span);
                *token = TokenTree::Group(group);
            }
        }
    }

    // Path segments cannot contain invisible delimiter group, so remove them if any.
    for i in (0..tokens.len().saturating_sub(3)).rev() {
        // Looking for a double colon
        if matches!(
            (&tokens[i + 1], &tokens[i + 2]),
            (TokenTree::Punct(a), TokenTree::Punct(b))
                if a.as_char() == ':' && a.spacing() == Spacing::Joint && b.as_char() == ':'
        ) {
            match &tokens[i + 3] {
                TokenTree::Group(group) if group.delimiter() == Delimiter::None => {
                    tokens.splice(i + 3..i + 4, group.stream());
                }
                _ => (),
            }

            match &tokens[i] {
                TokenTree::Group(group) if group.delimiter() == Delimiter::None => {
                    tokens.splice(i..i + 1, group.stream());
                }
                _ => (),
            }
        }
    }
}
