//! An attribute for easy generation of const functions with conditional compilations.
//!
//! # Examples
//!
//! ```rust
//! use const_fn::const_fn;
//!
//! // function is `const` on specified version and later compiler (including beta and nightly)
//! #[const_fn("1.36")]
//! pub const fn version() {
//!     /* ... */
//! }
//!
//! // function is `const` on nightly compiler (including dev build)
//! #[const_fn(nightly)]
//! pub const fn nightly() {
//!     /* ... */
//! }
//!
//! // function is `const` if `cfg(...)` is true
//! # #[cfg(any())]
//! #[const_fn(cfg(...))]
//! # pub fn _cfg() { unimplemented!() }
//! pub const fn cfg() {
//!     /* ... */
//! }
//!
//! // function is `const` if `cfg(feature = "...")` is true
//! #[const_fn(feature = "...")]
//! pub const fn feature() {
//!     /* ... */
//! }
//! ```
//!
//! # Alternatives
//!
//! This crate is proc-macro, but is very lightweight, and has no dependencies.
//!
//! You can manually define declarative macros with similar functionality (see [`if_rust_version`](https://github.com/ogoffart/if_rust_version#examples)), or [you can define the same function twice with different cfg](https://github.com/crossbeam-rs/crossbeam/blob/0b6ea5f69fde8768c1cfac0d3601e0b4325d7997/crossbeam-epoch/src/atomic.rs#L340-L372).
//! (Note: the former approach requires more macros to be defined depending on the number of version requirements, the latter approach requires more functions to be maintained manually)

#![doc(html_root_url = "https://docs.rs/const_fn/0.4.3")]
#![doc(test(
    no_crate_inject,
    attr(deny(warnings, rust_2018_idioms, single_use_lifetimes), allow(dead_code))
))]
#![forbid(unsafe_code)]
#![warn(future_incompatible, rust_2018_idioms, single_use_lifetimes, unreachable_pub)]
#![warn(clippy::all, clippy::default_trait_access)]
// mem::take, #[non_exhaustive], and Option::{as_deref, as_deref_mut} require Rust 1.40,
// matches! requires Rust 1.42, str::{strip_prefix, strip_suffix} requires Rust 1.45
#![allow(
    clippy::mem_replace_with_default,
    clippy::manual_non_exhaustive,
    clippy::option_as_ref_deref,
    clippy::match_like_matches_macro,
    clippy::manual_strip
)]

// older compilers require explicit `extern crate`.
#[allow(unused_extern_crates)]
extern crate proc_macro;

#[macro_use]
mod utils;

mod ast;
mod error;
mod iter;
mod to_tokens;

use proc_macro::{Delimiter, TokenStream, TokenTree};
use std::str::FromStr;

use crate::{
    ast::{Func, LitStr},
    error::Error,
    to_tokens::ToTokens,
    utils::{cfg_attrs, parse_as_empty, tt_span},
};

type Result<T, E = Error> = std::result::Result<T, E>;

/// An attribute for easy generation of const functions with conditional compilations.
/// See crate level documentation for details.
#[proc_macro_attribute]
pub fn const_fn(args: TokenStream, input: TokenStream) -> TokenStream {
    let arg = match parse_arg(args) {
        Ok(arg) => arg,
        Err(e) => return e.to_compile_error(),
    };
    let func = match ast::parse_input(input) {
        Ok(func) => func,
        Err(e) => return e.to_compile_error(),
    };

    expand(arg, func)
}

fn expand(arg: Arg, mut func: Func) -> TokenStream {
    match arg {
        Arg::Cfg(cfg) => {
            let (mut tokens, cfg_not) = cfg_attrs(cfg);
            tokens.extend(func.to_token_stream());
            tokens.extend(cfg_not);
            func.print_const = false;
            tokens.extend(func.to_token_stream());
            tokens
        }
        Arg::Feature(feat) => {
            let (mut tokens, cfg_not) = cfg_attrs(feat);
            tokens.extend(func.to_token_stream());
            tokens.extend(cfg_not);
            func.print_const = false;
            tokens.extend(func.to_token_stream());
            tokens
        }
        Arg::Version(req) => {
            if req.major > 1 || req.minor > VERSION.minor {
                func.print_const = false;
            }
            func.to_token_stream()
        }
        Arg::Nightly => {
            func.print_const = VERSION.nightly;
            func.to_token_stream()
        }
    }
}

enum Arg {
    // `const_fn("...")`
    Version(VersionReq),
    // `const_fn(nightly)`
    Nightly,
    // `const_fn(cfg(...))`
    Cfg(TokenStream),
    // `const_fn(feature = "...")`
    Feature(TokenStream),
}

fn parse_arg(tokens: TokenStream) -> Result<Arg> {
    let mut iter = tokens.into_iter();

    let next = iter.next();
    let next_span = tt_span(next.as_ref());
    match next {
        Some(TokenTree::Ident(i)) => match &*i.to_string() {
            "nightly" => {
                parse_as_empty(iter)?;
                return Ok(Arg::Nightly);
            }
            "cfg" => {
                return match iter.next().as_ref() {
                    Some(TokenTree::Group(g)) if g.delimiter() == Delimiter::Parenthesis => {
                        parse_as_empty(iter)?;
                        Ok(Arg::Cfg(g.stream()))
                    }
                    tt => Err(error!(tt_span(tt), "expected `(`")),
                };
            }
            "feature" => {
                let next = iter.next();
                return match next.as_ref() {
                    Some(TokenTree::Punct(p)) if p.as_char() == '=' => match iter.next() {
                        Some(TokenTree::Literal(l)) => {
                            let l = LitStr::new(l)?;
                            parse_as_empty(iter)?;
                            Ok(Arg::Feature(
                                vec![TokenTree::Ident(i), next.unwrap(), l.token.into()]
                                    .into_iter()
                                    .collect(),
                            ))
                        }
                        tt => Err(error!(tt_span(tt.as_ref()), "expected string literal")),
                    },
                    tt => Err(error!(tt_span(tt), "expected `=`")),
                };
            }
            _ => {}
        },
        Some(TokenTree::Literal(l)) => {
            if let Ok(l) = LitStr::new(l) {
                parse_as_empty(iter)?;
                return match l.value().parse::<VersionReq>() {
                    Ok(req) => Ok(Arg::Version(req)),
                    Err(e) => Err(error!(l.span(), "{}", e)),
                };
            }
        }
        _ => {}
    }

    Err(error!(next_span, "expected one of: `nightly`, `cfg`, `feature`, string literal"))
}

struct VersionReq {
    major: u32,
    minor: u32,
}

impl FromStr for VersionReq {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let mut pieces = s.split('.');
        let major = pieces
            .next()
            .ok_or("need to specify the major version")?
            .parse::<u32>()
            .map_err(|e| e.to_string())?;
        let minor = pieces
            .next()
            .ok_or("need to specify the minor version")?
            .parse::<u32>()
            .map_err(|e| e.to_string())?;
        if let Some(s) = pieces.next() {
            Err(format!("unexpected input: .{}", s))
        } else {
            Ok(Self { major, minor })
        }
    }
}

struct Version {
    minor: u32,
    nightly: bool,
}

#[cfg(const_fn_has_build_script)]
const VERSION: Version = include!(concat!(env!("OUT_DIR"), "/version.rs"));
// If build script has not run or unable to determine version, it is considered as Rust 1.0.
#[cfg(not(const_fn_has_build_script))]
const VERSION: Version = Version { minor: 0, nightly: false };
