using GsaEditor.Core.Compression;

namespace GsaEditor.Core.Models;

/// <summary>
/// Represents a single file entry within a GSA archive.
/// </summary>
public class GsaEntry
{
    /// <summary>
    /// Relative path (alias) of the file within the archive, using '/' as separator.
    /// Maximum 511 characters.
    /// </summary>
    public string Alias { get; set; } = string.Empty;

    /// <summary>
    /// Whether this entry's data is zlib-compressed.
    /// </summary>
    public bool IsCompressed { get; set; }

    /// <summary>
    /// Original (decompressed) size of the file in bytes.
    /// </summary>
    public uint OriginalLength { get; set; }

    /// <summary>
    /// Compressed size of the file in bytes. Equal to <see cref="OriginalLength"/> if not compressed.
    /// </summary>
    public uint CompressedLength { get; set; }

    /// <summary>
    /// Raw data as stored in the archive (compressed bytes if <see cref="IsCompressed"/> is true).
    /// </summary>
    public byte[] RawData { get; set; } = Array.Empty<byte>();

    /// <summary>
    /// Byte offset of this entry's data block within the archive file.
    /// </summary>
    public long DataOffset { get; set; }

    /// <summary>
    /// Returns the decompressed data for this entry.
    /// If the entry is not compressed, returns <see cref="RawData"/> directly.
    /// </summary>
    /// <returns>The decompressed file content.</returns>
    public byte[] GetDecompressedData()
    {
        if (!IsCompressed)
            return RawData;

        return ZlibHelper.Decompress(RawData, OriginalLength);
    }

    /// <summary>
    /// Sets the entry data from uncompressed bytes, optionally compressing with zlib.
    /// Updates <see cref="OriginalLength"/>, <see cref="CompressedLength"/>,
    /// <see cref="IsCompressed"/>, and <see cref="RawData"/>.
    /// </summary>
    /// <param name="uncompressedData">The uncompressed file content.</param>
    /// <param name="compress">Whether to compress the data with zlib.</param>
    public void SetData(byte[] uncompressedData, bool compress)
    {
        OriginalLength = (uint)uncompressedData.Length;
        IsCompressed = compress;

        if (compress)
        {
            RawData = ZlibHelper.Compress(uncompressedData);
            CompressedLength = (uint)RawData.Length;
        }
        else
        {
            RawData = uncompressedData;
            CompressedLength = OriginalLength;
        }
    }
}
