using System.Diagnostics;

namespace SoulstormReplayReader.Core.Utils;

internal sealed class NativeDowRandom
{
    public uint Seed { get; set; }
    public uint Index { get; set; }
    public uint IterLimit { get; set; }

    public int Lock { get; set; }

    public NativeDowRandom(uint iterLimit = 4u)
    {
        IterLimit = iterLimit;
    }

    public NativeDowRandom SetSeed(uint seed)
    {
        Seed = seed;
        Index = 0;

        return this;
    }

    public int GetMax(uint num)
    {
        if (num == 0) return 0;
        var res = (int)(HashRandom() % num);
        Debug.WriteLine($"{num} {res}");
        return res;
    }

    public int GetMax(int num) => GetMax((uint)num);

    #region Dow decompiled code

    private uint HashRandom()
    {
        var result = Index;
        Index++;
        var seed = Seed;

        if (IterLimit == 0) return result;

        for (var ind = 0; ind < IterLimit; ind++)
        {
            var s4 = result ^ s_arr1[ind];
            var s5 = result;
            var s6 = (ushort)s4;
            s4 >>= 16;
            var s7 = s_arr2[ind] ^ RotateLeft4((uint)(s6 * s6 + ~(s4 * s4)), '\x10');
            result = (seed ^ (s6 * s4 + s7));
            seed = s5;
        }

        return result;
    }

    private static uint RotateLeft4(uint x, char n) => (x << n) | (x >> (32 - n));

    private static readonly uint[] s_arr1 =
    {
        3131664519, 504877868, 62708796, 255054258, 1990609181,
        3312506973, 3816993251, 2027635554, 1949936084, 2632616645,
        2303949916, 629732701, 1096506909, 560872853, 2244371175,
        1586148200, 1051053196, 3530166132, 4087947819, 1219155940,
        0, 0, 0, 0
    };

    private static readonly uint[] s_arr2 =
    {
        1259289432, 3899977923, 1767228838, 1437059654, 1301978502,
        4264075669, 2982836325, 1797478225, 2593749601, 2859374024,
        2863238881, 1526273356, 4237173347, 957308556, 1493161986,
        2886360762, 2890429686, 2849966355, 2260618356, 3979088443,
        0, 0, 0, 0
    };

    #endregion
}