// Copyright 2018 The proptest developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Provides a parser from syn attributes to our logical model.

use syn::{self, Meta, NestedMeta, Lit, Ident, Attribute, Expr, Type};

use crate::util;
use crate::interp;
use crate::error::{self, Ctx, DeriveResult};

//==============================================================================
// Public API
//==============================================================================

/// Parsed attributes in our logical model.
#[derive(Clone)]
pub struct ParsedAttributes {
    /// If we've been ordered to skip this item.
    /// This is only valid for enum variants.
    pub skip: bool,
    /// The potential weight assigned to an enum variant.
    /// This must be `None` for things that are not enum variants.
    pub weight: Option<u32>,
    /// The mode for `Parameters` to use. See that type for more.
    pub params: ParamsMode,
    /// The mode for `Strategy` to use. See that type for more.
    pub strategy: StratMode,
    /// Filter expressions if any.
    pub filter: Vec<syn::Expr>,
    /// True if no_bound was specified.
    pub no_bound: bool,
}

/// The mode for the associated item `Strategy` to use.
#[derive(Clone)]
pub enum StratMode {
    /// This means that no explicit strategy was specified
    /// and that we thus should use `Arbitrary` for whatever
    /// it is that needs a strategy.
    Arbitrary,
    /// This means that an explicit value has been provided.
    /// The result of this is to use a strategy that always
    /// returns the given value.
    Value(Expr),
    /// This means that an explicit strategy has been provided.
    /// This strategy will be used to generate whatever it
    /// is that the attribute was set on.
    Strategy(Expr),
    /// This means that an explicit *regex* strategy has been provided.
    /// We don't reuse `Strategy(..)` so that we can produce better and
    /// more tailored error messages.
    Regex(Expr),
}

/// The mode for the associated item `Parameters` to use.
#[derive(Clone)]
pub enum ParamsMode {
    /// Nothing has been specified. The children are now free to
    /// specify their parameters, and if nothing is specified, then
    /// `<X as Arbitrary>::Parameters` will be used for a type `X`.
    Passthrough,
    /// We've been ordered to use the Default value of
    /// `<X as Arbitrary>::Parameters` for some field where applicable.
    /// For the top level item, this means that `Parameters` will be
    /// the unit type. For children, it means that this child should
    /// not count towards the product type that is being built up.
    Default,
    /// An explicit type has been specified on some item.
    /// If the top level item has this specified on it, this means
    /// that `Parameters` will have the given type.
    /// If it is specified on a child of the top level item, this
    /// entails that the given type will be added to the resultant
    /// product type.
    Specified(Type),
}

impl ParamsMode {
    /// Returns `true` iff the mode was explicitly set.
    pub fn is_set(&self) -> bool {
        if let ParamsMode::Passthrough = *self { false } else { true }
    }

    /// Converts the mode to an `Option` of an `Option` of a type
    /// where the outer `Option` is `None` iff the mode wasn't set
    /// and the inner `Option` is `None` iff the mode was `Default`.
    pub fn into_option(self) -> Option<Option<Type>> {
        use self::ParamsMode::*;
        match self {
            Passthrough => None,
            Specified(ty) => Some(Some(ty)),
            Default => Some(None),
        }
    }
}

impl StratMode {
    /// Returns `true` iff the mode was explicitly set.
    pub fn is_set(&self) -> bool {
        if let StratMode::Arbitrary = self { false } else { true }
    }
}

/// Parse the attributes specified on an item and parsed by syn
/// into our logical model that we work with.
pub fn parse_attributes(ctx: Ctx, attrs: &[Attribute])
    -> DeriveResult<ParsedAttributes>
{
    let attrs = parse_attributes_base(ctx, attrs)?;
    if attrs.no_bound {
        error::no_bound_set_on_non_tyvar(ctx);
    }
    Ok(attrs)
}

/// Parse the attributes specified on a type definition...
pub fn parse_top_attributes(ctx: Ctx, attrs: &[Attribute])
    -> DeriveResult<ParsedAttributes>
{
    parse_attributes_base(ctx, attrs)
}

/// Parses the attributes specified on an item and parsed by syn
/// and returns true if we've been ordered to not set an `Arbitrary`
/// bound on the given type variable the attributes are from,
/// no matter what.
pub fn has_no_bound(ctx: Ctx, attrs: &[Attribute]) -> DeriveResult<bool> {
    let attrs = parse_attributes_base(ctx, attrs)?;
    error::if_anything_specified(ctx, &attrs, error::TY_VAR);
    Ok(attrs.no_bound)
}

/// Parse the attributes specified on an item and parsed by syn
/// into our logical model that we work with.
fn parse_attributes_base(ctx: Ctx, attrs: &[Attribute])
    -> DeriveResult<ParsedAttributes>
{
    let acc = parse_accumulate(ctx, attrs);

    Ok(ParsedAttributes {
        skip: acc.skip.is_some(),
        weight: acc.weight,
        filter: acc.filter,
        // Process params and no_params together to see which one to use.
        params: parse_params_mode(ctx, acc.no_params, acc.params)?,
        // Process strategy and value together to see which one to use.
        strategy: parse_strat_mode(ctx, acc.strategy, acc.value, acc.regex)?,
        no_bound: acc.no_bound.is_some()
    })
}

//==============================================================================
// Internals: Initialization
//==============================================================================

/// The internal state of the attribute parser.
#[derive(Default)]
struct ParseAcc {
    skip: Option<()>,
    weight: Option<u32>,
    no_params: Option<()>,
    params: Option<Type>,
    strategy: Option<Expr>,
    value: Option<Expr>,
    regex: Option<Expr>,
    filter: Vec<Expr>,
    no_bound: Option<()>,
}

//==============================================================================
// Internals: Extraction & Filtering
//==============================================================================

fn parse_accumulate(ctx: Ctx, attrs: &[Attribute]) -> ParseAcc {
    let mut state = ParseAcc::default();

    // Get rid of attributes we don't care about:
    for attr in attrs {
        if is_proptest_attr(&attr) {
            // Flatten attributes so we deal with them uniformly.
            state = extract_modifiers(ctx, &attr).into_iter()
                // Accumulate attributes into a form for final processing.
                .fold(state, |state, meta| dispatch_attribute(ctx, state, meta))
        }
    }

    state
}

/// Returns `true` iff the attribute has to do with proptest.
/// Otherwise, the attribute is irrevant to us and we will simply
/// ignore it in our processing.
fn is_proptest_attr(attr: &Attribute) -> bool {
    util::eq_simple_path("proptest", &attr.path)
}

/// Extract all individual attributes inside one `#[proptest(..)]`.
/// We do this to treat all pieces uniformly whether a single
/// `#[proptest(..)]` was used or many. This simplifies the
/// logic somewhat.
fn extract_modifiers(ctx: Ctx, attr: &Attribute) -> Vec<Meta> {
    // Ensure we've been given an outer attribute form.
    if !is_outer_attr(&attr) {
        error::inner_attr(ctx);
    }

    match attr.interpret_meta() {
        Some(Meta::List(list)) => return list.nested.into_iter()
            .filter_map(|nm| extract_metas(ctx, nm)).collect(),
        Some(Meta::Word(_)) => error::bare_proptest_attr(ctx),
        Some(Meta::NameValue(_)) => error::literal_set_proptest(ctx),
        None => error::no_interp_meta(ctx),
    }

    vec![]
}

fn extract_metas(ctx: Ctx, nested: NestedMeta) -> Option<Meta> {
    match nested {
        NestedMeta::Literal(_) => {
            error::immediate_literals(ctx);
            None
        },
        // This is the only valid form.
        NestedMeta::Meta(meta) => Some(meta),
    }
}

/// Returns true iff the given attribute is an outer one, i.e: `#[<attr>]`.
/// An inner attribute is the other possibility and has the syntax `#![<attr>]`.
/// Note that `<attr>` is a meta-variable for the contents inside.
fn is_outer_attr(attr: &Attribute) -> bool {
    syn::AttrStyle::Outer == attr.style
}

//==============================================================================
// Internals: Dispatch
//==============================================================================

/// Dispatches an attribute modifier to handlers and
/// let's them add stuff into our accumulartor.
fn dispatch_attribute(ctx: Ctx, mut acc: ParseAcc, meta: Meta) -> ParseAcc {
    // Dispatch table for attributes:
    let name = meta.name().to_string();
    let name = name.as_ref();
    match name {
        // Valid modifiers:
        "skip" => parse_skip(ctx, &mut acc, meta),
        "w" | "weight" => parse_weight(ctx, &mut acc, &meta),
        "no_params" => parse_no_params(ctx, &mut acc, meta),
        "params" => parse_params(ctx, &mut acc, meta),
        "strategy" => parse_strategy(ctx, &mut acc, &meta),
        "value" => parse_value(ctx, &mut acc, &meta),
        "regex" => parse_regex(ctx, &mut acc, &meta),
        "filter" => parse_filter(ctx, &mut acc, &meta),
        "no_bound" => parse_no_bound(ctx, &mut acc, meta),
        // Invalid modifiers:
        name => dispatch_unknown_mod(ctx, name),
    }
    acc
}

fn dispatch_unknown_mod(ctx: Ctx, name: &str) {
    match name {
        "no_bounds" =>
            error::did_you_mean(ctx, name, "no_bound"),
        "weights" | "weighted" =>
            error::did_you_mean(ctx, name, "weight"),
        "strat" | "strategies" =>
            error::did_you_mean(ctx, name, "strategy"),
        "values" | "valued" | "fix" | "fixed" =>
            error::did_you_mean(ctx, name, "value"),
        "regexes" | "regexp" | "re" =>
            error::did_you_mean(ctx, name, "regex"),
        "param" | "parameters" =>
            error::did_you_mean(ctx, name, "params"),
        "no_param" | "no_parameters" =>
            error::did_you_mean(ctx, name, "no_params"),
        name =>
            error::unkown_modifier(ctx, name),
        // TODO: consider levenshtein distance.
    }
}

//==============================================================================
// Internals: no_bound
//==============================================================================

/// Parse a no_bound attribute.
/// Valid forms are:
/// + `#[proptest(no_bound)]`
fn parse_no_bound(ctx: Ctx, acc: &mut ParseAcc, meta: Meta) {
    parse_bare_modifier(ctx, &mut acc.no_bound, meta, error::no_bound_malformed)
}

//==============================================================================
// Internals: Skip
//==============================================================================

/// Parse a skip attribute.
/// Valid forms are:
/// + `#[proptest(skip)]`
fn parse_skip(ctx: Ctx, acc: &mut ParseAcc, meta: Meta) {
    parse_bare_modifier(ctx, &mut acc.skip, meta, error::skip_malformed)
}

//==============================================================================
// Internals: Weight
//==============================================================================

/// Parses a weight.
/// Valid forms are:
/// + `#[proptest(weight = <integer>)]`
/// + `#[proptest(weight = "<expr>")]`
/// + `#[proptest(weight(<integer>))]`
/// + `#[proptest(weight("<expr>""))]`
///
/// The `<integer>` must also fit within an `u32` and be unsigned.
fn parse_weight(ctx: Ctx, acc: &mut ParseAcc, meta: &Meta) {
    use std::u32;
    error_if_set(ctx, &acc.weight, &meta);

    // Convert to value if possible:
    let value = normalize_meta(meta.clone())
        .and_then(extract_lit)
        .and_then(extract_expr)
        // Evaluate the expression into a value:
        .as_ref().and_then(interp::eval_expr)
        // Ensure that `val` fits within an `u32` as proptest requires that:
        .filter(|&value| value <= u128::from(u32::MAX))
        .map(|value| value as u32);

    if let v@Some(_) = value {
        acc.weight = v;
    } else {
        error::weight_malformed(ctx, meta)
    }
}

//==============================================================================
// Internals: Filter
//==============================================================================

/// Parses an explicit value as a strategy.
/// Valid forms are:
/// + `#[proptest(filter(<ident>))]`
/// + `#[proptest(filter = "<expr>")]`
/// + `#[proptest(filter("<expr>")]`
fn parse_filter(ctx: Ctx, acc: &mut ParseAcc, meta: &Meta) {
    if let Some(filter) = match normalize_meta(meta.clone()) {
        Some(NormMeta::Lit(Lit::Str(lit))) => lit.parse().ok(),
        Some(NormMeta::Word(ident)) => Some(parse_quote!( #ident )),
        _ => None,
    } {
        acc.filter.push(filter);
    } else {
        error::filter_malformed(ctx, meta)
    }
}

//==============================================================================
// Internals: Strategy
//==============================================================================

/// Parses an explicit value as a strategy.
/// Valid forms are:
/// + `#[proptest(regex = "<string>")]`
/// + `#[proptest(regex("<string>")]`
/// + `#[proptest(regex(<ident>)]`
fn parse_regex(ctx: Ctx, acc: &mut ParseAcc, meta: &Meta) {
    error_if_set(ctx, &acc.regex, &meta);

    if let expr@Some(_) = match normalize_meta(meta.clone()) {
        Some(NormMeta::Word(fun)) => Some(function_call(fun)),
        Some(NormMeta::Lit(lit@Lit::Str(_))) => Some(lit_to_expr(lit)),
        _ => None,
    } {
        acc.regex = expr;
    } else {
        error::regex_malformed(ctx)
    }
}

/// Parses an explicit value as a strategy.
/// Valid forms are:
/// + `#[proptest(value = <literal>)]`
/// + `#[proptest(value = "<expr>")]`
/// + `#[proptest(value("<expr>")]`
/// + `#[proptest(value(<literal>)]`
/// + `#[proptest(value(<ident>)]`
fn parse_value(ctx: Ctx, acc: &mut ParseAcc, meta: &Meta) {
    parse_strategy_base(ctx, &mut acc.value, meta)
}

/// Parses an explicit strategy.
/// Valid forms are:
/// + `#[proptest(strategy = <literal>)]`
/// + `#[proptest(strategy = "<expr>")]`
/// + `#[proptest(strategy("<expr>")]`
/// + `#[proptest(strategy(<literal>)]`
/// + `#[proptest(strategy(<ident>)]`
fn parse_strategy(ctx: Ctx, acc: &mut ParseAcc, meta: &Meta) {
    parse_strategy_base(ctx, &mut acc.strategy, meta)
}

/// Parses an explicit strategy. This is a helper.
/// Valid forms are:
/// + `#[proptest(<meta.name()> = <literal>)]`
/// + `#[proptest(<meta.name()> = "<expr>")]`
/// + `#[proptest(<meta.name()>("<expr>")]`
/// + `#[proptest(<meta.name()>(<literal>)]`
/// + `#[proptest(<meta.name()>(<ident>)]`
fn parse_strategy_base(ctx: Ctx, loc: &mut Option<Expr>, meta: &Meta) {
    error_if_set(ctx, &loc, &meta);

    if let expr@Some(_) = match normalize_meta(meta.clone()) {
        Some(NormMeta::Word(fun)) => Some(function_call(fun)),
        Some(NormMeta::Lit(lit)) => extract_expr(lit),
        _ => None,
    } {
        *loc = expr;
    } else {
        error::strategy_malformed(ctx, meta)
    }
}

/// Combines any parsed explicit strategy, value, and regex into a single
/// value and fails if both an explicit strategy / value / regex was set.
/// Only one of them can be set, or none.
fn parse_strat_mode
    (ctx: Ctx, strat: Option<Expr>, value: Option<Expr>, regex: Option<Expr>)
    -> DeriveResult<StratMode>
{
    Ok(match (strat, value, regex) {
        (None,     None,     None    ) => StratMode::Arbitrary,
        (None,     None,     Some(re)) => StratMode::Regex(re),
        (None,     Some(vl), None    ) => StratMode::Value(vl),
        (Some(st), None,     None    ) => StratMode::Strategy(st),
        _ => error::overspecified_strat(ctx)?,
    })
}

//==============================================================================
// Internals: Parameters
//==============================================================================

/// Combines a potentially set `params` and `no_params` into a single value
/// and fails if both have been set. Only one of them can be set, or none.
fn parse_params_mode(ctx: Ctx, no_params: Option<()>, ty_params: Option<Type>)
    -> DeriveResult<ParamsMode>
{
    Ok(match (no_params, ty_params) {
        (None,    None    ) => ParamsMode::Passthrough,
        (None,    Some(ty)) => ParamsMode::Specified(ty),
        (Some(_), None    ) => ParamsMode::Default,
        (Some(_), Some(_) ) => error::overspecified_param(ctx)?,
    })
}

/// Parses an explicit Parameters type.
///
/// Valid forms are:
/// + `#[proptest(params(<type>)]`
/// + `#[proptest(params("<type>")]`
/// + `#[proptest(params = "<type>"]`
///
/// The latter form is required for more complex types.
fn parse_params(ctx: Ctx, acc: &mut ParseAcc, meta: Meta) {
    error_if_set(ctx, &acc.params, &meta);

    let typ = match normalize_meta(meta) {
        // Form is: `#[proptest(params(<type>)]`.
        Some(NormMeta::Word(ident)) => Some(ident_to_type(ident)),
        // Form is: `#[proptest(params = "<type>"]` or,
        // Form is: `#[proptest(params("<type>")]`..
        Some(NormMeta::Lit(Lit::Str(lit))) => lit.parse().ok(),
        _ => None,
    };

    if let typ@Some(_) = typ {
        acc.params = typ;
    } else {
        error::param_malformed(ctx)
    }
}

/// Parses an order to use the default Parameters type and value.
/// Valid forms are:
/// + `#[proptest(no_params)]`
fn parse_no_params(ctx: Ctx, acc: &mut ParseAcc, meta: Meta) {
    parse_bare_modifier(ctx, &mut acc.no_params, meta, error::no_params_malformed)
}

//==============================================================================
// Internals: Utilities
//==============================================================================

/// Parses a bare attribute of the form `#[proptest(<attr>)]` and sets `loc`.
fn parse_bare_modifier
    (ctx: Ctx, loc: &mut Option<()>, meta: Meta, malformed: fn(Ctx))
{
    error_if_set(ctx, loc, &meta);

    if let Some(NormMeta::Plain) = normalize_meta(meta) {
        *loc = Some(());
    } else {
        malformed(ctx);
    }
}

/// Emits a "set again" error iff the given option `.is_some()`.
fn error_if_set<T>(ctx: Ctx, loc: &Option<T>, meta: &Meta) {
    if loc.is_some() {
        error::set_again(ctx, meta)
    }
}

/// Constructs a type out of an identifier.
fn ident_to_type(ident: Ident) -> Type {
    Type::Path(syn::TypePath { qself: None, path: ident.into() })
}

/// Extract a `lit` in `NormMeta::Lit(<lit>)`.
fn extract_lit(meta: NormMeta) -> Option<Lit> {
    if let NormMeta::Lit(lit) = meta {
        Some(lit)
    } else {
        None
    }
}

/// Extract expression out of literal if possible.
fn extract_expr(lit: Lit) -> Option<Expr> {
    match lit {
        Lit::Str(lit) => lit.parse().ok(),
        lit@Lit::Int(_) => Some(lit_to_expr(lit)),
        // TODO(centril): generalize to other literals, e.g. floats
        _ => None,
    }
}

/// Construct an expression from a literal.
fn lit_to_expr(lit: Lit) -> Expr {
    syn::ExprLit { attrs: vec![], lit }.into()
}

/// Construct a function call expression for an identifier.
fn function_call(fun: Ident) -> Expr {
    parse_quote!( #fun() )
}

/// Normalized `Meta` into all the forms we will possibly accept.
#[derive(Debug)]
enum NormMeta {
    /// Accepts: `#[proptest(<word>)]`
    Plain,
    /// Accepts: `#[proptest(<word> = <lit>)]` and `#[proptest(<word>(<lit>))]`
    Lit(Lit),
    /// Accepts: `#[proptest(<word>(<word>))`.
    Word(Ident)
}

/// Normalize a `meta: Meta` into the forms accepted in `#[proptest(<meta>)]`.
fn normalize_meta(meta: Meta) -> Option<NormMeta> {
    Some(match meta {
        Meta::Word(_) => NormMeta::Plain,
        Meta::NameValue(nv) => NormMeta::Lit(nv.lit),
        Meta::List(ml) => if let Some(nm) = util::match_singleton(ml.nested) {
            match nm {
                NestedMeta::Literal(lit) => NormMeta::Lit(lit),
                NestedMeta::Meta(Meta::Word(word)) => NormMeta::Word(word),
                _ => return None
            }
        } else {
            return None
        },
    })
}
