// net48 compatibility shims. On net8 these APIs are in the BCL; net48 lacks them.
// (Language-feature polyfills — init/records/Index/Range/required — come from the
// PolySharp source generator; this file covers runtime helpers that PolySharp
// cannot supply because they live on existing BCL types.)

namespace System.Collections.Generic
{
    public static class Net48CollectionExtensions
    {
        /// <summary>
        /// Polyfill for CollectionExtensions.GetValueOrDefault (netstandard2.1+),
        /// absent on net48. Returns the value for <paramref name="key"/> or
        /// default(TValue) when the key is missing. Takes IDictionary rather than
        /// IReadOnlyDictionary: net40 (Windows XP flavor) predates the IReadOnly*
        /// interfaces, so shared code uses the classic ones throughout.
        /// </summary>
        public static TValue? GetValueOrDefault<TKey, TValue>(
            this IDictionary<TKey, TValue> dictionary, TKey key)
        {
            if (dictionary is null) throw new ArgumentNullException(nameof(dictionary));
            return dictionary.TryGetValue(key, out var value) ? value : default;
        }

        /// <summary>
        /// Polyfill for KeyValuePair&lt;,&gt;.Deconstruct (netstandard2.1+), absent on
        /// net48 — enables <c>foreach (var (k, v) in dictionary)</c>.
        /// </summary>
        public static void Deconstruct<TKey, TValue>(
            this KeyValuePair<TKey, TValue> pair, out TKey key, out TValue value)
        {
            key = pair.Key;
            value = pair.Value;
        }
    }
}

namespace RioJoy.Core.Compat
{
    internal static class Net48Math
    {
        /// <summary>
        /// Polyfill for Math.Clamp (netstandard2.1+), absent on net48. Returns
        /// <paramref name="value"/> bounded to [<paramref name="min"/>, <paramref name="max"/>].
        /// </summary>
        public static T Clamp<T>(T value, T min, T max) where T : IComparable<T>
        {
            if (min.CompareTo(max) > 0)
                throw new ArgumentException($"{nameof(min)} ({min}) cannot be greater than {nameof(max)} ({max}).");
            if (value.CompareTo(min) < 0) return min;
            if (value.CompareTo(max) > 0) return max;
            return value;
        }
    }
}
