use rustc_pattern_analysis::constructor::{
    Constructor, ConstructorSet, IntRange, MaybeInfiniteInt, RangeEnd, VariantVisibility,
};
use rustc_pattern_analysis::pat::DeconstructedPat;
use rustc_pattern_analysis::usefulness::{PlaceValidity, UsefulnessReport};
use rustc_pattern_analysis::{MatchArm, PatCx, PrivateUninhabitedField};

/// Sets up `tracing` for easier debugging. Tries to look like the `rustc` setup.
fn init_tracing() {
    use tracing_subscriber::Layer;
    use tracing_subscriber::layer::SubscriberExt;
    use tracing_subscriber::util::SubscriberInitExt;
    let _ = tracing_tree::HierarchicalLayer::default()
        .with_writer(std::io::stderr)
        .with_ansi(true)
        .with_targets(true)
        .with_indent_amount(2)
        .with_subscriber(
            tracing_subscriber::Registry::default()
                .with(tracing_subscriber::EnvFilter::from_default_env()),
        )
        .try_init();
}

/// A simple set of types.
#[allow(dead_code)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub(super) enum Ty {
    /// Booleans
    Bool,
    /// 8-bit unsigned integers
    U8,
    /// Tuples.
    Tuple(&'static [Ty]),
    /// Enum with one variant of each given type.
    Enum(&'static [Ty]),
    /// A struct with `arity` fields of type `ty`.
    BigStruct { arity: usize, ty: &'static Ty },
    /// A enum with `arity` variants of type `ty`.
    BigEnum { arity: usize, ty: &'static Ty },
}

/// The important logic.
impl Ty {
    pub(super) fn sub_tys(&self, ctor: &Constructor<Cx>) -> Vec<Self> {
        use Constructor::*;
        match (ctor, *self) {
            (Struct, Ty::Tuple(tys)) => tys.iter().copied().collect(),
            (Struct, Ty::BigStruct { arity, ty }) => (0..arity).map(|_| *ty).collect(),
            (Variant(i), Ty::Enum(tys)) => vec![tys[*i]],
            (Variant(_), Ty::BigEnum { ty, .. }) => vec![*ty],
            (Bool(..) | IntRange(..) | NonExhaustive | Missing | Wildcard, _) => vec![],
            _ => panic!("Unexpected ctor {ctor:?} for type {self:?}"),
        }
    }

    fn is_empty(&self) -> bool {
        match *self {
            Ty::Bool | Ty::U8 => false,
            Ty::Tuple(tys) => tys.iter().any(|ty| ty.is_empty()),
            Ty::Enum(tys) => tys.iter().all(|ty| ty.is_empty()),
            Ty::BigStruct { arity, ty } => arity != 0 && ty.is_empty(),
            Ty::BigEnum { arity, ty } => arity == 0 || ty.is_empty(),
        }
    }

    fn ctor_set(&self) -> ConstructorSet<Cx> {
        match *self {
            Ty::Bool => ConstructorSet::Bool,
            Ty::U8 => ConstructorSet::Integers {
                range_1: IntRange::from_range(
                    MaybeInfiniteInt::new_finite_uint(0),
                    MaybeInfiniteInt::new_finite_uint(255),
                    RangeEnd::Included,
                ),
                range_2: None,
            },
            Ty::Tuple(..) | Ty::BigStruct { .. } => ConstructorSet::Struct { empty: false },
            Ty::Enum(tys) if tys.is_empty() => ConstructorSet::NoConstructors,
            Ty::Enum(tys) => ConstructorSet::Variants {
                variants: tys
                    .iter()
                    .map(|ty| {
                        if ty.is_empty() {
                            VariantVisibility::Empty
                        } else {
                            VariantVisibility::Visible
                        }
                    })
                    .collect(),
                non_exhaustive: false,
            },
            Ty::BigEnum { arity: 0, .. } => ConstructorSet::NoConstructors,
            Ty::BigEnum { arity, ty } => {
                let vis = if ty.is_empty() {
                    VariantVisibility::Empty
                } else {
                    VariantVisibility::Visible
                };
                ConstructorSet::Variants {
                    variants: (0..arity).map(|_| vis).collect(),
                    non_exhaustive: false,
                }
            }
        }
    }

    fn write_variant_name(
        &self,
        f: &mut std::fmt::Formatter<'_>,
        ctor: &Constructor<Cx>,
    ) -> std::fmt::Result {
        match (*self, ctor) {
            (Ty::Tuple(..), _) => Ok(()),
            (Ty::BigStruct { .. }, _) => write!(f, "BigStruct"),
            (Ty::Enum(..), Constructor::Variant(i)) => write!(f, "Enum::Variant{i}"),
            (Ty::BigEnum { .. }, Constructor::Variant(i)) => write!(f, "BigEnum::Variant{i}"),
            _ => write!(f, "{:?}::{:?}", self, ctor),
        }
    }
}

/// Compute usefulness in our simple context (and set up tracing for easier debugging).
pub(super) fn compute_match_usefulness<'p>(
    arms: &[MatchArm<'p, Cx>],
    ty: Ty,
    scrut_validity: PlaceValidity,
    complexity_limit: usize,
) -> Result<UsefulnessReport<'p, Cx>, ()> {
    init_tracing();
    rustc_pattern_analysis::usefulness::compute_match_usefulness(
        &Cx,
        arms,
        ty,
        scrut_validity,
        complexity_limit,
    )
}

#[derive(Debug)]
pub(super) struct Cx;

/// The context for pattern analysis. Forwards anything interesting to `Ty` methods.
impl PatCx for Cx {
    type Ty = Ty;
    type Error = ();
    type VariantIdx = usize;
    type StrLit = ();
    type ArmData = ();
    type PatData = ();

    fn is_exhaustive_patterns_feature_on(&self) -> bool {
        false
    }

    fn ctor_arity(&self, ctor: &Constructor<Self>, ty: &Self::Ty) -> usize {
        ty.sub_tys(ctor).len()
    }

    fn ctor_sub_tys(
        &self,
        ctor: &Constructor<Self>,
        ty: &Self::Ty,
    ) -> impl Iterator<Item = (Self::Ty, PrivateUninhabitedField)> + ExactSizeIterator {
        ty.sub_tys(ctor).into_iter().map(|ty| (ty, PrivateUninhabitedField(false)))
    }

    fn ctors_for_ty(&self, ty: &Self::Ty) -> Result<ConstructorSet<Self>, Self::Error> {
        Ok(ty.ctor_set())
    }

    fn write_variant_name(
        f: &mut std::fmt::Formatter<'_>,
        ctor: &Constructor<Self>,
        ty: &Self::Ty,
    ) -> std::fmt::Result {
        ty.write_variant_name(f, ctor)
    }

    fn bug(&self, fmt: std::fmt::Arguments<'_>) -> Self::Error {
        panic!("{}", fmt)
    }

    /// Abort when reaching the complexity limit. This is what we'll check in tests.
    fn complexity_exceeded(&self) -> Result<(), Self::Error> {
        Err(())
    }

    fn report_mixed_deref_pat_ctors(
        &self,
        _deref_pat: &DeconstructedPat<Self>,
        _normal_pat: &DeconstructedPat<Self>,
    ) -> Self::Error {
        panic!("`rustc_pattern_analysis::tests` currently doesn't test deref pattern errors")
    }
}

/// Construct a single pattern; see `pats!()`.
#[allow(unused_macros)]
macro_rules! pat {
    ($($rest:tt)*) => {{
        let mut vec = pats!($($rest)*);
        vec.pop().unwrap()
    }};
}

/// A macro to construct patterns. Called like `pats!(type_expr; pattern, pattern, ..)` and returns
/// a `Vec<DeconstructedPat>`. A pattern can be nested and looks like `Constructor(pat, pat)` or
/// `Constructor { .i: pat, .j: pat }`, where `Constructor` is `Struct`, `Variant.i` (with index
/// `i`), as well as booleans and integer ranges.
///
/// The general structure of the macro is a tt-muncher with several stages identified with
/// `@something(args)`. The args are a key-value list (the keys ensure we don't mix the arguments
/// around) which is passed down and modified as needed. We then parse token-trees from
/// left-to-right. Non-trivial recursion happens when we parse the arguments to a pattern: we
/// recurse to parse the tokens inside `{..}`/`(..)`, and then we continue parsing anything that
/// follows.
macro_rules! pats {
    // Entrypoint
    // Parse `type; ..`
    ($ty:expr; $($rest:tt)*) => {{
        #[allow(unused_imports)]
        use rustc_pattern_analysis::{
            constructor::{Constructor, IntRange, MaybeInfiniteInt, RangeEnd},
            pat::DeconstructedPat,
        };
        let ty = $ty;
        // The heart of the macro is designed to push `IndexedPat`s into a `Vec`, so we work around
        // that.
        let sub_tys = ::std::iter::repeat(&ty);
        let mut vec = Vec::new();
        pats!(@ctor(vec:vec, sub_tys:sub_tys, idx:0) $($rest)*);
        vec.into_iter().map(|ipat| ipat.pat).collect::<Vec<_>>()
    }};

    // Parse `constructor ..`

    (@ctor($($args:tt)*) true $($rest:tt)*) => {{
        let ctor = Constructor::Bool(true);
        pats!(@pat($($args)*, ctor:ctor) $($rest)*)
    }};
    (@ctor($($args:tt)*) false $($rest:tt)*) => {{
        let ctor = Constructor::Bool(false);
        pats!(@pat($($args)*, ctor:ctor) $($rest)*)
    }};
    (@ctor($($args:tt)*) Struct $($rest:tt)*) => {{
        let ctor = Constructor::Struct;
        pats!(@pat($($args)*, ctor:ctor) $($rest)*)
    }};
    (@ctor($($args:tt)*) ( $($fields:tt)* ) $($rest:tt)*) => {{
        let ctor = Constructor::Struct; // tuples
        pats!(@pat($($args)*, ctor:ctor) ( $($fields)* ) $($rest)*)
    }};
    (@ctor($($args:tt)*) Variant.$variant:ident $($rest:tt)*) => {{
        let ctor = Constructor::Variant($variant);
        pats!(@pat($($args)*, ctor:ctor) $($rest)*)
    }};
    (@ctor($($args:tt)*) Variant.$variant:literal $($rest:tt)*) => {{
        let ctor = Constructor::Variant($variant);
        pats!(@pat($($args)*, ctor:ctor) $($rest)*)
    }};
    (@ctor($($args:tt)*) _ $($rest:tt)*) => {{
        let ctor = Constructor::Wildcard;
        pats!(@pat($($args)*, ctor:ctor) $($rest)*)
    }};

    // Integers and int ranges
    (@ctor($($args:tt)*) $($start:literal)?..$end:literal $($rest:tt)*) => {{
        let ctor = Constructor::IntRange(IntRange::from_range(
            pats!(@rangeboundary- $($start)?),
            pats!(@rangeboundary+ $end),
            RangeEnd::Excluded,
        ));
        pats!(@pat($($args)*, ctor:ctor) $($rest)*)
    }};
    (@ctor($($args:tt)*) $($start:literal)?.. $($rest:tt)*) => {{
        let ctor = Constructor::IntRange(IntRange::from_range(
            pats!(@rangeboundary- $($start)?),
            pats!(@rangeboundary+),
            RangeEnd::Excluded,
        ));
        pats!(@pat($($args)*, ctor:ctor) $($rest)*)
    }};
    (@ctor($($args:tt)*) $($start:literal)?..=$end:literal $($rest:tt)*) => {{
        let ctor = Constructor::IntRange(IntRange::from_range(
            pats!(@rangeboundary- $($start)?),
            pats!(@rangeboundary+ $end),
            RangeEnd::Included,
        ));
        pats!(@pat($($args)*, ctor:ctor) $($rest)*)
    }};
    (@ctor($($args:tt)*) $int:literal $($rest:tt)*) => {{
        let ctor = Constructor::IntRange(IntRange::from_range(
            pats!(@rangeboundary- $int),
            pats!(@rangeboundary+ $int),
            RangeEnd::Included,
        ));
        pats!(@pat($($args)*, ctor:ctor) $($rest)*)
    }};
    // Utility to manage range boundaries.
    (@rangeboundary $sign:tt $int:literal) => { MaybeInfiniteInt::new_finite_uint($int) };
    (@rangeboundary -) => { MaybeInfiniteInt::NegInfinity };
    (@rangeboundary +) => { MaybeInfiniteInt::PosInfinity };

    // Parse subfields: `(..)` or `{..}`

    // Constructor with no fields, e.g. `bool` or `Variant.1`.
    (@pat($($args:tt)*) $(,)?) => {
        pats!(@pat($($args)*) {})
    };
    (@pat($($args:tt)*) , $($rest:tt)*) => {
        pats!(@pat($($args)*) {}, $($rest)*)
    };
    // `(..)` and `{..}` are treated the same.
    (@pat($($args:tt)*) ( $($subpat:tt)* ) $($rest:tt)*) => {{
        pats!(@pat($($args)*) { $($subpat)* } $($rest)*)
    }};
    (@pat(vec:$vec:expr, sub_tys:$sub_tys:expr, idx:$idx:expr, ctor:$ctor:expr) { $($fields:tt)* } $($rest:tt)*) => {{
        let sub_tys = $sub_tys;
        let index = $idx;
        // Silly dance to work with both a vec and `iter::repeat()`.
        let ty = *(&sub_tys).clone().into_iter().nth(index).unwrap();
        let ctor = $ctor;
        let ctor_sub_tys = &ty.sub_tys(&ctor);
        #[allow(unused_mut)]
        let mut fields = Vec::new();
        // Parse subpatterns (note the leading comma).
        pats!(@fields(idx:0, vec:fields, sub_tys:ctor_sub_tys) ,$($fields)*);
        let arity = ctor_sub_tys.len();
        let pat = DeconstructedPat::new(ctor, fields, arity, ty, ()).at_index(index);
        $vec.push(pat);

        // Continue parsing further patterns.
        pats!(@fields(idx:index+1, vec:$vec, sub_tys:sub_tys) $($rest)*);
    }};

    // Parse fields one by one.

    // No fields left.
    (@fields($($args:tt)*) $(,)?) => {};
    // `.i: pat` sets the current index to `i`.
    (@fields(idx:$_idx:expr, $($args:tt)*) , .$idx:literal : $($rest:tt)*) => {{
        pats!(@ctor($($args)*, idx:$idx) $($rest)*);
    }};
    (@fields(idx:$_idx:expr, $($args:tt)*) , .$idx:ident : $($rest:tt)*) => {{
        pats!(@ctor($($args)*, idx:$idx) $($rest)*);
    }};
    // Field without an explicit index; we use the current index which gets incremented above.
    (@fields(idx:$idx:expr, $($args:tt)*) , $($rest:tt)*) => {{
        pats!(@ctor($($args)*, idx:$idx) $($rest)*);
    }};
}
