//! Intermediate representation for C/C++ enumerations.

use super::super::codegen::EnumVariation;
use super::context::{BindgenContext, TypeId};
use super::item::Item;
use super::ty::{Type, TypeKind};
use crate::clang;
use crate::ir::annotations::Annotations;
use crate::parse::{ClangItemParser, ParseError};
use crate::regex_set::RegexSet;

/// An enum representing custom handling that can be given to a variant.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum EnumVariantCustomBehavior {
    /// This variant will be a module containing constants.
    ModuleConstify,
    /// This variant will be constified, that is, forced to generate a constant.
    Constify,
    /// This variant will be hidden entirely from the resulting enum.
    Hide,
}

/// A C/C++ enumeration.
#[derive(Debug)]
pub struct Enum {
    /// The representation used for this enum; it should be an `IntKind` type or
    /// an alias to one.
    ///
    /// It's `None` if the enum is a forward declaration and isn't defined
    /// anywhere else, see `tests/headers/func_ptr_in_struct.h`.
    repr: Option<TypeId>,

    /// The different variants, with explicit values.
    variants: Vec<EnumVariant>,
}

impl Enum {
    /// Construct a new `Enum` with the given representation and variants.
    pub fn new(repr: Option<TypeId>, variants: Vec<EnumVariant>) -> Self {
        Enum { repr, variants }
    }

    /// Get this enumeration's representation.
    pub fn repr(&self) -> Option<TypeId> {
        self.repr
    }

    /// Get this enumeration's variants.
    pub fn variants(&self) -> &[EnumVariant] {
        &self.variants
    }

    /// Construct an enumeration from the given Clang type.
    pub fn from_ty(
        ty: &clang::Type,
        ctx: &mut BindgenContext,
    ) -> Result<Self, ParseError> {
        use clang_sys::*;
        debug!("Enum::from_ty {:?}", ty);

        if ty.kind() != CXType_Enum {
            return Err(ParseError::Continue);
        }

        let declaration = ty.declaration().canonical();
        let repr = declaration
            .enum_type()
            .and_then(|et| Item::from_ty(&et, declaration, None, ctx).ok());
        let mut variants = vec![];

        let variant_ty =
            repr.and_then(|r| ctx.resolve_type(r).safe_canonical_type(ctx));
        let is_bool = variant_ty.map_or(false, Type::is_bool);

        // Assume signedness since the default type by the C standard is an int.
        let is_signed = variant_ty.map_or(true, |ty| match *ty.kind() {
            TypeKind::Int(ref int_kind) => int_kind.is_signed(),
            ref other => {
                panic!("Since when enums can be non-integers? {:?}", other)
            }
        });

        let type_name = ty.spelling();
        let type_name = if type_name.is_empty() {
            None
        } else {
            Some(type_name)
        };
        let type_name = type_name.as_ref().map(String::as_str);

        let definition = declaration.definition().unwrap_or(declaration);
        definition.visit(|cursor| {
            if cursor.kind() == CXCursor_EnumConstantDecl {
                let value = if is_bool {
                    cursor.enum_val_boolean().map(EnumVariantValue::Boolean)
                } else if is_signed {
                    cursor.enum_val_signed().map(EnumVariantValue::Signed)
                } else {
                    cursor.enum_val_unsigned().map(EnumVariantValue::Unsigned)
                };
                if let Some(val) = value {
                    let name = cursor.spelling();
                    let annotations = Annotations::new(&cursor);
                    let custom_behavior = ctx
                        .parse_callbacks()
                        .and_then(|callbacks| {
                            callbacks
                                .enum_variant_behavior(type_name, &name, val)
                        })
                        .or_else(|| {
                            let annotations = annotations.as_ref()?;
                            if annotations.hide() {
                                Some(EnumVariantCustomBehavior::Hide)
                            } else if annotations.constify_enum_variant() {
                                Some(EnumVariantCustomBehavior::Constify)
                            } else {
                                None
                            }
                        });

                    let new_name = ctx
                        .parse_callbacks()
                        .and_then(|callbacks| {
                            callbacks.enum_variant_name(type_name, &name, val)
                        })
                        .or_else(|| {
                            annotations
                                .as_ref()?
                                .use_instead_of()?
                                .last()
                                .cloned()
                        })
                        .unwrap_or_else(|| name.clone());

                    let comment = cursor.raw_comment();
                    variants.push(EnumVariant::new(
                        new_name,
                        name,
                        comment,
                        val,
                        custom_behavior,
                    ));
                }
            }
            CXChildVisit_Continue
        });
        Ok(Enum::new(repr, variants))
    }

    fn is_matching_enum(
        &self,
        ctx: &BindgenContext,
        enums: &RegexSet,
        item: &Item,
    ) -> bool {
        let path = item.path_for_allowlisting(ctx);
        let enum_ty = item.expect_type();

        if enums.matches(&path[1..].join("::")) {
            return true;
        }

        // Test the variants if the enum is anonymous.
        if enum_ty.name().is_some() {
            return false;
        }

        self.variants().iter().any(|v| enums.matches(&v.name()))
    }

    /// Returns the final representation of the enum.
    pub fn computed_enum_variation(
        &self,
        ctx: &BindgenContext,
        item: &Item,
    ) -> EnumVariation {
        // ModuleConsts has higher precedence before Rust in order to avoid
        // problems with overlapping match patterns.
        if self.is_matching_enum(
            ctx,
            &ctx.options().constified_enum_modules,
            item,
        ) {
            EnumVariation::ModuleConsts
        } else if self.is_matching_enum(
            ctx,
            &ctx.options().bitfield_enums,
            item,
        ) {
            EnumVariation::NewType { is_bitfield: true }
        } else if self.is_matching_enum(ctx, &ctx.options().newtype_enums, item)
        {
            EnumVariation::NewType { is_bitfield: false }
        } else if self.is_matching_enum(
            ctx,
            &ctx.options().rustified_enums,
            item,
        ) {
            EnumVariation::Rust {
                non_exhaustive: false,
            }
        } else if self.is_matching_enum(
            ctx,
            &ctx.options().rustified_non_exhaustive_enums,
            item,
        ) {
            EnumVariation::Rust {
                non_exhaustive: true,
            }
        } else if self.is_matching_enum(
            ctx,
            &ctx.options().constified_enums,
            item,
        ) {
            EnumVariation::Consts
        } else {
            ctx.options().default_enum_style
        }
    }
}

/// A single enum variant, to be contained only in an enum.
#[derive(Debug)]
pub struct EnumVariant {
    /// The name of the variant.
    name: String,

    /// The original name of the variant (without user mangling)
    name_for_allowlisting: String,

    /// An optional doc comment.
    comment: Option<String>,

    /// The integer value of the variant.
    val: EnumVariantValue,

    /// The custom behavior this variant may have, if any.
    custom_behavior: Option<EnumVariantCustomBehavior>,
}

/// A constant value assigned to an enumeration variant.
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum EnumVariantValue {
    /// A boolean constant.
    Boolean(bool),

    /// A signed constant.
    Signed(i64),

    /// An unsigned constant.
    Unsigned(u64),
}

impl EnumVariant {
    /// Construct a new enumeration variant from the given parts.
    pub fn new(
        name: String,
        name_for_allowlisting: String,
        comment: Option<String>,
        val: EnumVariantValue,
        custom_behavior: Option<EnumVariantCustomBehavior>,
    ) -> Self {
        EnumVariant {
            name,
            name_for_allowlisting,
            comment,
            val,
            custom_behavior,
        }
    }

    /// Get this variant's name.
    pub fn name(&self) -> &str {
        &self.name
    }

    /// Get this variant's name.
    pub fn name_for_allowlisting(&self) -> &str {
        &self.name_for_allowlisting
    }

    /// Get this variant's value.
    pub fn val(&self) -> EnumVariantValue {
        self.val
    }

    /// Get this variant's documentation.
    pub fn comment(&self) -> Option<&str> {
        self.comment.as_ref().map(|s| &**s)
    }

    /// Returns whether this variant should be enforced to be a constant by code
    /// generation.
    pub fn force_constification(&self) -> bool {
        self.custom_behavior
            .map_or(false, |b| b == EnumVariantCustomBehavior::Constify)
    }

    /// Returns whether the current variant should be hidden completely from the
    /// resulting rust enum.
    pub fn hidden(&self) -> bool {
        self.custom_behavior
            .map_or(false, |b| b == EnumVariantCustomBehavior::Hide)
    }
}
