use core::{
    fmt,
    ops::{BitAnd, BitOr, BitXor, Not},
};

use crate::{
    iter,
    parser::{ParseError, ParseHex, WriteHex},
};

/**
A defined flags value that may be named or unnamed.
*/
#[derive(Debug)]
pub struct Flag<B> {
    name: &'static str,
    value: B,
}

impl<B> Flag<B> {
    /**
    Define a flag.

    If `name` is non-empty then the flag is named, otherwise it's unnamed.
    */
    pub const fn new(name: &'static str, value: B) -> Self {
        Flag { name, value }
    }

    /**
    Get the name of this flag.

    If the flag is unnamed then the returned string will be empty.
    */
    pub const fn name(&self) -> &'static str {
        self.name
    }

    /**
    Get the flags value of this flag.
    */
    pub const fn value(&self) -> &B {
        &self.value
    }

    /**
    Whether the flag is named.

    If [`Flag::name`] returns a non-empty string then this method will return `true`.
    */
    pub const fn is_named(&self) -> bool {
        !self.name.is_empty()
    }

    /**
    Whether the flag is unnamed.

    If [`Flag::name`] returns a non-empty string then this method will return `false`.
    */
    pub const fn is_unnamed(&self) -> bool {
        self.name.is_empty()
    }
}

/**
A set of defined flags using a bits type as storage.

## Implementing `Flags`

This trait is implemented by the [`bitflags`](macro.bitflags.html) macro:

```
use bitflags::bitflags;

bitflags! {
    struct MyFlags: u8 {
        const A = 1;
        const B = 1 << 1;
    }
}
```

It can also be implemented manually:

```
use bitflags::{Flag, Flags};

struct MyFlags(u8);

impl Flags for MyFlags {
    const FLAGS: &'static [Flag<Self>] = &[
        Flag::new("A", MyFlags(1)),
        Flag::new("B", MyFlags(1 << 1)),
    ];

    type Bits = u8;

    fn from_bits_retain(bits: Self::Bits) -> Self {
        MyFlags(bits)
    }

    fn bits(&self) -> Self::Bits {
        self.0
    }
}
```

## Using `Flags`

The `Flags` trait can be used generically to work with any flags types. In this example,
we can count the number of defined named flags:

```
# use bitflags::{bitflags, Flags};
fn defined_flags<F: Flags>() -> usize {
    F::FLAGS.iter().filter(|f| f.is_named()).count()
}

bitflags! {
    struct MyFlags: u8 {
        const A = 1;
        const B = 1 << 1;
        const C = 1 << 2;

        const _ = !0;
    }
}

assert_eq!(3, defined_flags::<MyFlags>());
```
*/
pub trait Flags: Sized + 'static {
    /// The set of defined flags.
    const FLAGS: &'static [Flag<Self>];

    /// The underlying bits type.
    type Bits: Bits;

    /// Get a flags value with all bits unset.
    fn empty() -> Self {
        Self::from_bits_retain(Self::Bits::EMPTY)
    }

    /// Get a flags value with all known bits set.
    fn all() -> Self {
        let mut truncated = Self::Bits::EMPTY;

        for flag in Self::FLAGS.iter() {
            truncated = truncated | flag.value().bits();
        }

        Self::from_bits_retain(truncated)
    }

    /// Get the underlying bits value.
    ///
    /// The returned value is exactly the bits set in this flags value.
    fn bits(&self) -> Self::Bits;

    /// Convert from a bits value.
    ///
    /// This method will return `None` if any unknown bits are set.
    fn from_bits(bits: Self::Bits) -> Option<Self> {
        let truncated = Self::from_bits_truncate(bits);

        if truncated.bits() == bits {
            Some(truncated)
        } else {
            None
        }
    }

    /// Convert from a bits value, unsetting any unknown bits.
    fn from_bits_truncate(bits: Self::Bits) -> Self {
        Self::from_bits_retain(bits & Self::all().bits())
    }

    /// Convert from a bits value exactly.
    fn from_bits_retain(bits: Self::Bits) -> Self;

    /// Get a flags value with the bits of a flag with the given name set.
    ///
    /// This method will return `None` if `name` is empty or doesn't
    /// correspond to any named flag.
    fn from_name(name: &str) -> Option<Self> {
        // Don't parse empty names as empty flags
        if name.is_empty() {
            return None;
        }

        for flag in Self::FLAGS {
            if flag.name() == name {
                return Some(Self::from_bits_retain(flag.value().bits()));
            }
        }

        None
    }

    /// Yield a set of contained flags values.
    ///
    /// Each yielded flags value will correspond to a defined named flag. Any unknown bits
    /// will be yielded together as a final flags value.
    fn iter(&self) -> iter::Iter<Self> {
        iter::Iter::new(self)
    }

    /// Yield a set of contained named flags values.
    ///
    /// This method is like [`Flags::iter`], except only yields bits in contained named flags.
    /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded.
    fn iter_names(&self) -> iter::IterNames<Self> {
        iter::IterNames::new(self)
    }

    /// Whether all bits in this flags value are unset.
    fn is_empty(&self) -> bool {
        self.bits() == Self::Bits::EMPTY
    }

    /// Whether all known bits in this flags value are set.
    fn is_all(&self) -> bool {
        // NOTE: We check against `Self::all` here, not `Self::Bits::ALL`
        // because the set of all flags may not use all bits
        Self::all().bits() | self.bits() == self.bits()
    }

    /// Whether any set bits in a source flags value are also set in a target flags value.
    fn intersects(&self, other: Self) -> bool
    where
        Self: Sized,
    {
        self.bits() & other.bits() != Self::Bits::EMPTY
    }

    /// Whether all set bits in a source flags value are also set in a target flags value.
    fn contains(&self, other: Self) -> bool
    where
        Self: Sized,
    {
        self.bits() & other.bits() == other.bits()
    }

    /// The bitwise or (`|`) of the bits in two flags values.
    fn insert(&mut self, other: Self)
    where
        Self: Sized,
    {
        *self = Self::from_bits_retain(self.bits()).union(other);
    }

    /// The intersection of a source flags value with the complement of a target flags value (`&!`).
    ///
    /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
    /// `remove` won't truncate `other`, but the `!` operator will.
    fn remove(&mut self, other: Self)
    where
        Self: Sized,
    {
        *self = Self::from_bits_retain(self.bits()).difference(other);
    }

    /// The bitwise exclusive-or (`^`) of the bits in two flags values.
    fn toggle(&mut self, other: Self)
    where
        Self: Sized,
    {
        *self = Self::from_bits_retain(self.bits()).symmetric_difference(other);
    }

    /// Call [`Flags::insert`] when `value` is `true` or [`Flags::remove`] when `value` is `false`.
    fn set(&mut self, other: Self, value: bool)
    where
        Self: Sized,
    {
        if value {
            self.insert(other);
        } else {
            self.remove(other);
        }
    }

    /// The bitwise and (`&`) of the bits in two flags values.
    #[must_use]
    fn intersection(self, other: Self) -> Self {
        Self::from_bits_retain(self.bits() & other.bits())
    }

    /// The bitwise or (`|`) of the bits in two flags values.
    #[must_use]
    fn union(self, other: Self) -> Self {
        Self::from_bits_retain(self.bits() | other.bits())
    }

    /// The intersection of a source flags value with the complement of a target flags value (`&!`).
    ///
    /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
    /// `difference` won't truncate `other`, but the `!` operator will.
    #[must_use]
    fn difference(self, other: Self) -> Self {
        Self::from_bits_retain(self.bits() & !other.bits())
    }

    /// The bitwise exclusive-or (`^`) of the bits in two flags values.
    #[must_use]
    fn symmetric_difference(self, other: Self) -> Self {
        Self::from_bits_retain(self.bits() ^ other.bits())
    }

    /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
    #[must_use]
    fn complement(self) -> Self {
        Self::from_bits_truncate(!self.bits())
    }
}

/**
A bits type that can be used as storage for a flags type.
*/
pub trait Bits:
    Clone
    + Copy
    + PartialEq
    + BitAnd<Output = Self>
    + BitOr<Output = Self>
    + BitXor<Output = Self>
    + Not<Output = Self>
    + Sized
    + 'static
{
    /// A value with all bits unset.
    const EMPTY: Self;

    /// A value with all bits set.
    const ALL: Self;
}

// Not re-exported: prevent custom `Bits` impls being used in the `bitflags!` macro,
// or they may fail to compile based on crate features
pub trait Primitive {}

macro_rules! impl_bits {
    ($($u:ty, $i:ty,)*) => {
        $(
            impl Bits for $u {
                const EMPTY: $u = 0;
                const ALL: $u = <$u>::MAX;
            }

            impl Bits for $i {
                const EMPTY: $i = 0;
                const ALL: $i = <$u>::MAX as $i;
            }

            impl ParseHex for $u {
                fn parse_hex(input: &str) -> Result<Self, ParseError> {
                    <$u>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input))
                }
            }

            impl ParseHex for $i {
                fn parse_hex(input: &str) -> Result<Self, ParseError> {
                    <$i>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input))
                }
            }

            impl WriteHex for $u {
                fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
                    write!(writer, "{:x}", self)
                }
            }

            impl WriteHex for $i {
                fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
                    write!(writer, "{:x}", self)
                }
            }

            impl Primitive for $i {}
            impl Primitive for $u {}
        )*
    }
}

impl_bits! {
    u8, i8,
    u16, i16,
    u32, i32,
    u64, i64,
    u128, i128,
    usize, isize,
}

/// A trait for referencing the `bitflags`-owned internal type
/// without exposing it publicly.
pub trait PublicFlags {
    /// The type of the underlying storage.
    type Primitive: Primitive;

    /// The type of the internal field on the generated flags type.
    type Internal;
}

#[doc(hidden)]
#[deprecated(note = "use the `Flags` trait instead")]
pub trait BitFlags: ImplementedByBitFlagsMacro + Flags {
    /// An iterator over enabled flags in an instance of the type.
    type Iter: Iterator<Item = Self>;

    /// An iterator over the raw names and bits for enabled flags in an instance of the type.
    type IterNames: Iterator<Item = (&'static str, Self)>;
}

#[allow(deprecated)]
impl<B: Flags> BitFlags for B {
    type Iter = iter::Iter<Self>;
    type IterNames = iter::IterNames<Self>;
}

impl<B: Flags> ImplementedByBitFlagsMacro for B {}

/// A marker trait that signals that an implementation of `BitFlags` came from the `bitflags!` macro.
///
/// There's nothing stopping an end-user from implementing this trait, but we don't guarantee their
/// manual implementations won't break between non-breaking releases.
#[doc(hidden)]
pub trait ImplementedByBitFlagsMacro {}

pub(crate) mod __private {
    pub use super::{ImplementedByBitFlagsMacro, PublicFlags};
}
