// SPDX-License-Identifier: MIT or Apache-2.0 or GPL-2.0-or-later

// shadowing is useful together with "if let"
#![allow(clippy::shadow_unrelated)]

use proc_macro2::{
    Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree, TokenTree as TT,
};

use crate::utils::MacroError;

pub struct BitsConstInternal {
    typ: TokenTree,
}

fn paren(ts: TokenStream) -> TokenTree {
    TT::Group(Group::new(Delimiter::Parenthesis, ts))
}

fn ident(s: &'static str) -> TokenTree {
    TT::Ident(Ident::new(s, Span::call_site()))
}

fn punct(ch: char) -> TokenTree {
    TT::Punct(Punct::new(ch, Spacing::Alone))
}

/// Implements a recursive-descent parser that translates Boolean expressions on
/// bitmasks to invocations of `const` functions defined by the `bits!` macro.
impl BitsConstInternal {
    // primary ::= '(' or ')'
    //           | ident
    //           | '!' ident
    fn parse_primary(
        &self,
        tok: TokenTree,
        it: &mut dyn Iterator<Item = TokenTree>,
        out: &mut TokenStream,
    ) -> Result<Option<TokenTree>, MacroError> {
        let next = match tok {
            TT::Group(ref g) => {
                if g.delimiter() != Delimiter::Parenthesis && g.delimiter() != Delimiter::None {
                    return Err(MacroError::Message("expected parenthesis".into(), g.span()));
                }
                let mut stream = g.stream().into_iter();
                let Some(first_tok) = stream.next() else {
                    return Err(MacroError::Message(
                        "expected operand, found ')'".into(),
                        g.span(),
                    ));
                };
                let mut output = TokenStream::new();
                // start from the lowest precedence
                let next = self.parse_or(first_tok, &mut stream, &mut output)?;
                if let Some(tok) = next {
                    return Err(MacroError::Message(
                        format!("unexpected token {tok}"),
                        tok.span(),
                    ));
                }
                out.extend(Some(paren(output)));
                it.next()
            }
            TT::Ident(_) => {
                let mut output = TokenStream::new();
                output.extend([
                    self.typ.clone(),
                    TT::Punct(Punct::new(':', Spacing::Joint)),
                    TT::Punct(Punct::new(':', Spacing::Joint)),
                    tok,
                ]);
                out.extend(Some(paren(output)));
                it.next()
            }
            TT::Punct(ref p) => {
                if p.as_char() != '!' {
                    return Err(MacroError::Message("expected operand".into(), p.span()));
                }
                let Some(rhs_tok) = it.next() else {
                    return Err(MacroError::Message(
                        "expected operand at end of input".into(),
                        p.span(),
                    ));
                };
                let next = self.parse_primary(rhs_tok, it, out)?;
                out.extend([punct('.'), ident("invert"), paren(TokenStream::new())]);
                next
            }
            _ => {
                return Err(MacroError::Message("unexpected literal".into(), tok.span()));
            }
        };
        Ok(next)
    }

    fn parse_binop<
        F: Fn(
            &Self,
            TokenTree,
            &mut dyn Iterator<Item = TokenTree>,
            &mut TokenStream,
        ) -> Result<Option<TokenTree>, MacroError>,
    >(
        &self,
        tok: TokenTree,
        it: &mut dyn Iterator<Item = TokenTree>,
        out: &mut TokenStream,
        ch: char,
        f: F,
        method: &'static str,
    ) -> Result<Option<TokenTree>, MacroError> {
        let mut next = f(self, tok, it, out)?;
        while next.is_some() {
            let op = next.as_ref().unwrap();
            let TT::Punct(ref p) = op else { break };
            if p.as_char() != ch {
                break;
            }

            let Some(rhs_tok) = it.next() else {
                return Err(MacroError::Message(
                    "expected operand at end of input".into(),
                    p.span(),
                ));
            };
            let mut rhs = TokenStream::new();
            next = f(self, rhs_tok, it, &mut rhs)?;
            out.extend([punct('.'), ident(method), paren(rhs)]);
        }
        Ok(next)
    }

    // sub ::= primary ('-' primary)*
    pub fn parse_sub(
        &self,
        tok: TokenTree,
        it: &mut dyn Iterator<Item = TokenTree>,
        out: &mut TokenStream,
    ) -> Result<Option<TokenTree>, MacroError> {
        self.parse_binop(tok, it, out, '-', Self::parse_primary, "difference")
    }

    // and ::= sub ('&' sub)*
    fn parse_and(
        &self,
        tok: TokenTree,
        it: &mut dyn Iterator<Item = TokenTree>,
        out: &mut TokenStream,
    ) -> Result<Option<TokenTree>, MacroError> {
        self.parse_binop(tok, it, out, '&', Self::parse_sub, "intersection")
    }

    // xor ::= and ('&' and)*
    fn parse_xor(
        &self,
        tok: TokenTree,
        it: &mut dyn Iterator<Item = TokenTree>,
        out: &mut TokenStream,
    ) -> Result<Option<TokenTree>, MacroError> {
        self.parse_binop(tok, it, out, '^', Self::parse_and, "symmetric_difference")
    }

    // or ::= xor ('|' xor)*
    pub fn parse_or(
        &self,
        tok: TokenTree,
        it: &mut dyn Iterator<Item = TokenTree>,
        out: &mut TokenStream,
    ) -> Result<Option<TokenTree>, MacroError> {
        self.parse_binop(tok, it, out, '|', Self::parse_xor, "union")
    }

    pub fn parse(
        it: &mut dyn Iterator<Item = TokenTree>,
    ) -> Result<proc_macro2::TokenStream, MacroError> {
        let mut pos = Span::call_site();
        let mut typ = proc_macro2::TokenStream::new();

        // Gobble everything up to an `@` sign, which is followed by a
        // parenthesized expression; that is, all token trees except the
        // last two form the type.
        let next = loop {
            let tok = it.next();
            if let Some(ref t) = tok {
                pos = t.span();
            }
            match tok {
                None => break None,
                Some(TT::Punct(ref p)) if p.as_char() == '@' => {
                    let tok = it.next();
                    if let Some(ref t) = tok {
                        pos = t.span();
                    }
                    break tok;
                }
                Some(x) => typ.extend(Some(x)),
            }
        };

        let Some(tok) = next else {
            return Err(MacroError::Message(
                "expected expression, do not call this macro directly".into(),
                pos,
            ));
        };
        let TT::Group(ref _group) = tok else {
            return Err(MacroError::Message(
                "expected parenthesis, do not call this macro directly".into(),
                tok.span(),
            ));
        };
        let mut out = TokenStream::new();
        let state = Self {
            typ: TT::Group(Group::new(Delimiter::None, typ)),
        };

        let next = state.parse_primary(tok, it, &mut out)?;

        // A parenthesized expression is a single production of the grammar,
        // so the input must have reached the last token.
        if let Some(tok) = next {
            return Err(MacroError::Message(
                format!("unexpected token {tok}"),
                tok.span(),
            ));
        }
        Ok(out)
    }
}
