using System.Reflection;

namespace Wonderking.Game;

public abstract class DataReader<T>
{
    protected DataReader(string path)
    {
        Path = path;
        DatFileContent = new(GetDatFileContent(path).ToArray());
    }

    private protected string Path { get; init; }

    public abstract uint GetAmountOfEntries();
    public abstract T GetEntry(uint entryId);

    protected ushort GetSizeOfEntry()
    {
        return typeof(T).GetCustomAttribute<GameDataMetadataAttribute>()?.DataEntrySize ??
               throw new NotSupportedException("DataEntrySize is null");
    }

    private static string GetDatFileName()
    {
        return typeof(T).GetCustomAttribute<GameDataMetadataAttribute>()?.DatFileName ??
               throw new NotSupportedException("DatFileName is null");
    }

    private static byte GetXorKey()
    {
        return typeof(T).GetCustomAttribute<GameDataMetadataAttribute>()?.XorKey ??
               throw new NotSupportedException("XorKey is null");
    }

    protected MemoryStream DatFileContent { get; }

    private static Span<byte> GetDatFileContent(string path)
    {
        var fileData = File.ReadAllBytes(path + GetDatFileName());
        var data = new byte[fileData.Length];

        for (var i = 0; i < fileData.Length; i++)
        {
            data[i] = (byte)(fileData[i] ^ GetXorKey());
        }

        return data;
    }
}