//! Configuration for skipping or changing the result for individual test cases (inputs) rather
//! than ignoring entire tests.

use CheckBasis::{Mpfr, Musl};
use libm::support::CastFrom;
use {BaseName as Bn, Identifier as Id};

use crate::{BaseName, CheckBasis, CheckCtx, Float, Identifier, Int, TestResult};

/// Type implementing [`IgnoreCase`].
pub struct SpecialCase;

/// ULP allowed to differ from the results returned by a test basis.
#[allow(clippy::single_match)]
pub fn default_ulp(ctx: &CheckCtx) -> u32 {
    // ULP compared to the infinite (MPFR) result.
    let mut ulp = match ctx.base_name {
        // Operations that require exact results. This list should correlate with what we
        // have documented at <https://doc.rust-lang.org/std/primitive.f32.html>.
        Bn::Ceil
        | Bn::Copysign
        | Bn::Fabs
        | Bn::Fdim
        | Bn::Floor
        | Bn::Fma
        | Bn::Fmax
        | Bn::Fmaximum
        | Bn::FmaximumNum
        | Bn::Fmin
        | Bn::Fminimum
        | Bn::FminimumNum
        | Bn::Fmod
        | Bn::Frexp
        | Bn::Ilogb
        | Bn::Ldexp
        | Bn::Modf
        | Bn::Nextafter
        | Bn::Remainder
        | Bn::Remquo
        | Bn::Rint
        | Bn::Round
        | Bn::Roundeven
        | Bn::Scalbn
        | Bn::Sqrt
        | Bn::Trunc => 0,

        // Operations that aren't required to be exact, but our implementations are.
        Bn::Cbrt => 0,

        // Bessel functions have large inaccuracies.
        Bn::J0 | Bn::J1 | Bn::Y0 | Bn::Y1 | Bn::Jn | Bn::Yn => 8_000_000,

        // For all other operations, specify our implementation's worst case precision.
        Bn::Acos => 1,
        Bn::Acosh => 4,
        Bn::Asin => 1,
        Bn::Asinh => 2,
        Bn::Atan => 1,
        Bn::Atan2 => 2,
        Bn::Atanh => 2,
        Bn::Cos => 1,
        Bn::Cosh => 1,
        Bn::Erf => 1,
        Bn::Erfc => 4,
        Bn::Exp => 1,
        Bn::Exp10 => 6,
        Bn::Exp2 => 1,
        Bn::Expm1 => 1,
        Bn::Hypot => 1,
        Bn::Lgamma | Bn::LgammaR => 16,
        Bn::Log => 1,
        Bn::Log10 => 1,
        Bn::Log1p => 1,
        Bn::Log2 => 1,
        Bn::Pow => 1,
        Bn::Sin => 1,
        Bn::Sincos => 1,
        Bn::Sinh => 2,
        Bn::Tan => 1,
        Bn::Tanh => 2,
        // tgammaf has higher accuracy than tgamma.
        Bn::Tgamma if ctx.fn_ident != Id::Tgamma => 1,
        Bn::Tgamma => 20,
    };

    // These have a separate implementation on i586
    if cfg!(x86_no_sse) {
        match ctx.fn_ident {
            Id::Exp => ulp = 1,
            Id::Exp2 => ulp = 1,
            Id::Exp10 => ulp = 1,
            Id::Expf => ulp = 0,
            Id::Exp2f => ulp = 0,
            Id::Exp10f => ulp = 0,
            _ => (),
        }
    }

    // There are some cases where musl's approximation is less accurate than ours. For these
    // cases, increase the ULP.
    if ctx.basis == Musl {
        match ctx.base_name {
            Bn::Cosh => ulp = 2,
            Bn::Exp10 if usize::BITS < 64 => ulp = 4,
            Bn::Lgamma | Bn::LgammaR => ulp = 400,
            Bn::Tanh => ulp = 4,
            _ => (),
        }

        match ctx.fn_ident {
            Id::Cbrt => ulp = 2,
            // FIXME(#401): musl has an incorrect result here.
            Id::Fdim => ulp = 2,
            Id::Exp2f => ulp = 1,
            Id::Expf => ulp = 1,
            Id::Sincosf => ulp = 500,
            Id::Tgamma => ulp = 20,
            _ => (),
        }
    }

    if cfg!(target_arch = "x86") {
        match ctx.fn_ident {
            // Input `fma(0.999999999999999, 1.0000000000000013, 0.0) = 1.0000000000000002` is
            // incorrect on i586 and i686.
            Id::Fma => ulp = 1,
            _ => (),
        }
    }

    // In some cases, our implementation is less accurate than musl on i586.
    if cfg!(x86_no_sse) {
        match ctx.fn_ident {
            // FIXME(#401): these need to be correctly rounded but are not.
            Id::Fmaf => ulp = 1,
            Id::Fdim => ulp = 1,
            Id::Round => ulp = 1,

            Id::Asinh => ulp = 3,
            Id::Asinhf => ulp = 3,
            Id::Cbrt => ulp = 1,
            Id::Log1p | Id::Log1pf => ulp = 2,
            Id::Tan => ulp = 2,
            _ => (),
        }
    }

    ulp
}

/// Result of checking for possible overrides.
#[derive(Debug, Default)]
pub enum CheckAction {
    /// The check should pass. Default case.
    #[default]
    AssertSuccess,

    /// Override the ULP for this check.
    AssertWithUlp(u32),

    /// Failure is expected, ensure this is the case (xfail). Takes a contxt string to help trace
    /// back exactly why we expect this to fail.
    AssertFailure(&'static str),

    /// The override somehow validated the result, here it is.
    Custom(TestResult),

    /// Disregard the output.
    Skip,
}

/// Don't run further validation on this test case.
const SKIP: CheckAction = CheckAction::Skip;

/// Return this to skip checks on a test that currently fails but shouldn't. Takes a description
/// of context.
const XFAIL: fn(&'static str) -> CheckAction = CheckAction::AssertFailure;

/// Indicates that we expect a test to fail but we aren't asserting that it does (e.g. some results
/// within a range do actually pass).
///
/// Same as `SKIP`, just indicates we have something to eventually fix.
const XFAIL_NOCHECK: CheckAction = CheckAction::Skip;

/// By default, all tests should pass.
const DEFAULT: CheckAction = CheckAction::AssertSuccess;

/// Allow overriding the outputs of specific test cases.
///
/// There are some cases where we want to xfail specific cases or handle certain inputs
/// differently than the rest of calls to `validate`. This provides a hook to do that.
///
/// If `None` is returned, checks will proceed as usual. If `Some(result)` is returned, checks
/// are skipped and the provided result is returned instead.
///
/// This gets implemented once per input type, then the functions provide further filtering
/// based on function name and values.
///
/// `ulp` can also be set to adjust the ULP for that specific test, even if `None` is still
/// returned.
pub trait MaybeOverride<Input> {
    fn check_float<F: Float>(
        _input: Input,
        _actual: F,
        _expected: F,
        _ctx: &CheckCtx,
    ) -> CheckAction {
        DEFAULT
    }

    fn check_int<I: Int>(_input: Input, _actual: I, _expected: I, _ctx: &CheckCtx) -> CheckAction {
        DEFAULT
    }
}

#[cfg(f16_enabled)]
impl MaybeOverride<(f16,)> for SpecialCase {}

impl MaybeOverride<(f32,)> for SpecialCase {
    fn check_float<F: Float>(input: (f32,), actual: F, expected: F, ctx: &CheckCtx) -> CheckAction {
        if (ctx.base_name == BaseName::Lgamma || ctx.base_name == BaseName::LgammaR)
            && input.0 > 4e36
            && expected.is_infinite()
            && !actual.is_infinite()
        {
            // This result should saturate but we return a finite value.
            return XFAIL_NOCHECK;
        }

        if ctx.base_name == BaseName::J0 && input.0 < -1e34 {
            // Errors get huge close to -inf
            return XFAIL_NOCHECK;
        }

        unop_common(input, actual, expected, ctx)
    }

    fn check_int<I: Int>(input: (f32,), actual: I, expected: I, ctx: &CheckCtx) -> CheckAction {
        // On MPFR for lgammaf_r, we set -1 as the integer result for negative infinity but MPFR
        // sets +1
        if ctx.basis == CheckBasis::Mpfr
            && ctx.base_name == BaseName::LgammaR
            && input.0 == f32::NEG_INFINITY
            && actual.abs() == expected.abs()
        {
            return XFAIL("lgammar integer result");
        }

        DEFAULT
    }
}

impl MaybeOverride<(f64,)> for SpecialCase {
    fn check_float<F: Float>(input: (f64,), actual: F, expected: F, ctx: &CheckCtx) -> CheckAction {
        if cfg!(x86_no_sse)
            && (ctx.base_name == BaseName::Rint || ctx.base_name == BaseName::Roundeven)
            && (expected - actual).abs() <= F::ONE
            && (expected - actual).abs() > F::ZERO
        {
            // Our rounding mode is incorrect.
            return XFAIL("i586 rint rounding mode");
        }

        if ctx.base_name == BaseName::J0 && input.0 < -1e300 {
            // Errors get huge close to -inf
            return XFAIL_NOCHECK;
        }

        // maybe_check_nan_bits(actual, expected, ctx)
        unop_common(input, actual, expected, ctx)
    }

    fn check_int<I: Int>(input: (f64,), actual: I, expected: I, ctx: &CheckCtx) -> CheckAction {
        // On MPFR for lgamma_r, we set -1 as the integer result for negative infinity but MPFR
        // sets +1
        if ctx.basis == CheckBasis::Mpfr
            && ctx.base_name == BaseName::LgammaR
            && input.0 == f64::NEG_INFINITY
            && actual.abs() == expected.abs()
        {
            return XFAIL("lgammar integer result");
        }

        DEFAULT
    }
}

#[cfg(f128_enabled)]
impl MaybeOverride<(f128,)> for SpecialCase {}

// F1 and F2 are always the same type, this is just to please generics
fn unop_common<F1: Float, F2: Float>(
    input: (F1,),
    actual: F2,
    expected: F2,
    ctx: &CheckCtx,
) -> CheckAction {
    if ctx.base_name == BaseName::Acosh
        && input.0 < F1::NEG_ONE
        && !(expected.is_nan() && actual.is_nan())
    {
        // acoshf is undefined for x <= 1.0, but we return a random result at lower values.

        if ctx.basis == CheckBasis::Musl {
            return XFAIL_NOCHECK;
        }

        return XFAIL("acoshf undefined");
    }

    if (ctx.base_name == BaseName::Lgamma || ctx.base_name == BaseName::LgammaR)
        && input.0 < F1::ZERO
        && !input.0.is_infinite()
    {
        // loggamma should not be defined for x < 0, yet we both return results
        return XFAIL_NOCHECK;
    }

    // fabs and copysign must leave NaNs untouched.
    if ctx.base_name == BaseName::Fabs && input.0.is_nan() {
        // LLVM currently uses x87 instructions which quieten signalling NaNs to handle the i686
        // `extern "C"` `f32`/`f64` return ABI.
        // LLVM issue <https://github.com/llvm/llvm-project/issues/66803>
        // Rust issue <https://github.com/rust-lang/rust/issues/115567>
        if cfg!(target_arch = "x86") && ctx.basis == CheckBasis::Musl && actual.is_nan() {
            return XFAIL_NOCHECK;
        }

        // MPFR only has one NaN bitpattern; allow the default `.is_nan()` checks to validate.
        if ctx.basis == CheckBasis::Mpfr {
            return DEFAULT;
        }

        // abs and copysign require signaling NaNs to be propagated, so verify bit equality.
        if actual.biteq(expected) {
            return CheckAction::Custom(Ok(()));
        } else {
            return CheckAction::Custom(Err(anyhow::anyhow!("NaNs have different bitpatterns")));
        }
    }

    DEFAULT
}

#[cfg(f16_enabled)]
impl MaybeOverride<(f16, f16)> for SpecialCase {
    fn check_float<F: Float>(
        input: (f16, f16),
        actual: F,
        expected: F,
        ctx: &CheckCtx,
    ) -> CheckAction {
        binop_common(input, actual, expected, ctx)
    }
}

impl MaybeOverride<(f32, f32)> for SpecialCase {
    fn check_float<F: Float>(
        input: (f32, f32),
        actual: F,
        expected: F,
        ctx: &CheckCtx,
    ) -> CheckAction {
        binop_common(input, actual, expected, ctx)
    }
}

impl MaybeOverride<(f64, f64)> for SpecialCase {
    fn check_float<F: Float>(
        input: (f64, f64),
        actual: F,
        expected: F,
        ctx: &CheckCtx,
    ) -> CheckAction {
        binop_common(input, actual, expected, ctx)
    }
}

#[cfg(f128_enabled)]
impl MaybeOverride<(f128, f128)> for SpecialCase {
    fn check_float<F: Float>(
        input: (f128, f128),
        actual: F,
        expected: F,
        ctx: &CheckCtx,
    ) -> CheckAction {
        binop_common(input, actual, expected, ctx)
    }
}

// F1 and F2 are always the same type, this is just to please generics
fn binop_common<F1: Float, F2: Float>(
    input: (F1, F1),
    actual: F2,
    expected: F2,
    ctx: &CheckCtx,
) -> CheckAction {
    // MPFR only has one NaN bitpattern; skip tests in cases where the first argument would take
    // the sign of a NaN second argument. The default NaN checks cover other cases.
    if ctx.base_name == BaseName::Copysign && ctx.basis == CheckBasis::Mpfr && input.1.is_nan() {
        return SKIP;
    }

    // FIXME(#939): this should not be skipped, there is a bug in our implementationi.
    if ctx.base_name == BaseName::FmaximumNum
        && ctx.basis == CheckBasis::Mpfr
        && ((input.0.is_nan() && actual.is_nan() && expected.is_nan()) || input.1.is_nan())
    {
        return XFAIL_NOCHECK;
    }

    /* FIXME(#439): our fmin and fmax do not compare signed zeros */

    if ctx.base_name == BaseName::Fmin
        && input.0.biteq(F1::NEG_ZERO)
        && input.1.biteq(F1::ZERO)
        && expected.biteq(F2::NEG_ZERO)
        && actual.biteq(F2::ZERO)
    {
        return XFAIL("fmin signed zeroes");
    }

    if ctx.base_name == BaseName::Fmax
        && input.0.biteq(F1::NEG_ZERO)
        && input.1.biteq(F1::ZERO)
        && expected.biteq(F2::ZERO)
        && actual.biteq(F2::NEG_ZERO)
    {
        return XFAIL("fmax signed zeroes");
    }

    // Musl propagates NaNs if one is provided as the input, but we return the other input.
    if (ctx.base_name == BaseName::Fmax || ctx.base_name == BaseName::Fmin)
        && ctx.basis == Musl
        && (input.0.is_nan() ^ input.1.is_nan())
        && expected.is_nan()
    {
        return XFAIL("fmax/fmin musl NaN");
    }

    DEFAULT
}

impl MaybeOverride<(i32, f32)> for SpecialCase {
    fn check_float<F: Float>(
        input: (i32, f32),
        actual: F,
        expected: F,
        ctx: &CheckCtx,
    ) -> CheckAction {
        // `ynf(213, 109.15641) = -inf` with our library, should be finite.
        if ctx.basis == Mpfr
            && ctx.base_name == BaseName::Yn
            && input.0 > 200
            && !expected.is_infinite()
            && actual.is_infinite()
        {
            return XFAIL("ynf infinity mismatch");
        }

        int_float_common(input, actual, expected, ctx)
    }
}

impl MaybeOverride<(i32, f64)> for SpecialCase {
    fn check_float<F: Float>(
        input: (i32, f64),
        actual: F,
        expected: F,
        ctx: &CheckCtx,
    ) -> CheckAction {
        int_float_common(input, actual, expected, ctx)
    }
}

fn int_float_common<F1: Float, F2: Float>(
    input: (i32, F1),
    actual: F2,
    expected: F2,
    ctx: &CheckCtx,
) -> CheckAction {
    if ctx.basis == Mpfr
        && (ctx.base_name == BaseName::Jn || ctx.base_name == BaseName::Yn)
        && input.1 == F1::NEG_INFINITY
        && actual == F2::ZERO
        && expected == F2::ZERO
    {
        return XFAIL("we disagree with MPFR on the sign of zero");
    }

    // Values near infinity sometimes get cut off for us. `ynf(681, 509.90924) = -inf` but should
    // be -3.2161271e38.
    if ctx.basis == Musl
        && ctx.fn_ident == Identifier::Ynf
        && !expected.is_infinite()
        && actual.is_infinite()
        && (expected.abs().to_bits().abs_diff(actual.abs().to_bits())
            < F2::Int::cast_from(10_000_000u32))
    {
        return XFAIL_NOCHECK;
    }

    // Our bessel functions blow up with large N values
    if ctx.basis == Musl && (ctx.base_name == BaseName::Jn || ctx.base_name == BaseName::Yn) {
        if cfg!(x86_no_sse) {
            // Precision is especially bad on i586, not worth checking.
            return XFAIL_NOCHECK;
        }

        if input.0 > 4000 {
            return XFAIL_NOCHECK;
        } else if input.0 > 100 {
            return CheckAction::AssertWithUlp(1_000_000);
        }
    }
    DEFAULT
}

#[cfg(f16_enabled)]
impl MaybeOverride<(f16, i32)> for SpecialCase {}
impl MaybeOverride<(f32, i32)> for SpecialCase {}
impl MaybeOverride<(f64, i32)> for SpecialCase {}
#[cfg(f128_enabled)]
impl MaybeOverride<(f128, i32)> for SpecialCase {}

impl MaybeOverride<(f32, f32, f32)> for SpecialCase {}
impl MaybeOverride<(f64, f64, f64)> for SpecialCase {}
#[cfg(f128_enabled)]
impl MaybeOverride<(f128, f128, f128)> for SpecialCase {}
