using System;

namespace MyParking.Shared
{
    // 统一拒绝跨层数据中的NaN、无穷大和不符合正负范围的数值。
    public static class NumericGuard
    {
        // 判断浮点数是否为有限值。
        public static bool IsFinite(double value)
        {
            return !double.IsNaN(value) &&
                   !double.IsInfinity(value);
        }

        // 拒绝NaN和无穷大。
        public static void EnsureFinite(
            double value,
            string parameterName)
        {
            if (!IsFinite(value))
            {
                throw new ArgumentOutOfRangeException(
                    parameterName,
                    "参数必须是有限值。");
            }
        }

        // 拒绝负数、NaN和无穷大。
        public static void EnsureFiniteNonNegative(
            double value,
            string parameterName)
        {
            EnsureFinite(value, parameterName);

            if (value < 0.0)
            {
                throw new ArgumentOutOfRangeException(
                    parameterName,
                    "参数必须是非负有限值。");
            }
        }

        // 拒绝零、负数、NaN和无穷大。
        public static void EnsureFinitePositive(
            double value,
            string parameterName)
        {
            EnsureFinite(value, parameterName);

            if (value <= 0.0)
            {
                throw new ArgumentOutOfRangeException(
                    parameterName,
                    "参数必须是正有限值。");
            }
        }

        // 同时检查二维位姿的位置和航向。
        public static void EnsureFinite(
            Pose2D pose,
            string parameterName)
        {
            if (!IsFinite(pose.XMeters) ||
                !IsFinite(pose.YMeters) ||
                !IsFinite(pose.YawRadians))
            {
                throw new ArgumentOutOfRangeException(
                    parameterName,
                    "二维位姿必须由有限值组成。");
            }
        }

        // 同时检查二维刚体速度的两个线速度分量和角速度。
        public static void EnsureFinite(
            Twist2D twist,
            string parameterName)
        {
            if (!IsFinite(twist.VxMetersPerSecond) ||
                !IsFinite(twist.VyMetersPerSecond) ||
                !IsFinite(twist.OmegaRadiansPerSecond))
            {
                throw new ArgumentOutOfRangeException(
                    parameterName,
                    "二维刚体速度必须由有限值组成。");
            }
        }
    }
}
