#nullable disable

using SharpCompress.IO;

namespace SharpCompress.Common.Rar.Headers
{
    internal class ArchiveCryptHeader : RarHeader
    {

        private const int CRYPT_VERSION = 0; // Supported encryption version.
        private const int SIZE_SALT50 = 16;
        private const int SIZE_SALT30 = 8;
        private const int SIZE_INITV = 16;
        private const int SIZE_PSWCHECK = 8;
        private const int SIZE_PSWCHECK_CSUM = 4;
        private const int CRYPT5_KDF_LG2_COUNT = 15; // LOG2 of PDKDF2 iteration count.
        private const int CRYPT5_KDF_LG2_COUNT_MAX = 24; // LOG2 of maximum accepted iteration count.


        private bool _usePswCheck;
        private uint _lg2Count; // Log2 of PBKDF2 repetition count.
        private byte[] _salt;
        private byte[] _pswCheck;
        private byte[] _pswCheckCsm;

        public ArchiveCryptHeader(RarHeader header, RarCrcBinaryReader reader)
            : base(header, reader, HeaderType.Crypt)
        {
        }

        protected override void ReadFinish(MarkingBinaryReader reader)
        {
            var cryptVersion = reader.ReadRarVIntUInt32();
            if (cryptVersion > CRYPT_VERSION)
            {
                //error?
                return;
            }
            var encryptionFlags = reader.ReadRarVIntUInt32();
            _usePswCheck = FlagUtility.HasFlag(encryptionFlags, EncryptionFlagsV5.CHFL_CRYPT_PSWCHECK);
            _lg2Count = reader.ReadRarVIntByte(1);


            //UsePswCheck = HasHeaderFlag(EncryptionFlagsV5.CHFL_CRYPT_PSWCHECK);
            if (_lg2Count > CRYPT5_KDF_LG2_COUNT_MAX)
            {
                //error?
                return;
            }

            _salt = reader.ReadBytes(SIZE_SALT50);
            if (_usePswCheck)
            {
                _pswCheck = reader.ReadBytes(SIZE_PSWCHECK);
                _pswCheckCsm = reader.ReadBytes(SIZE_PSWCHECK_CSUM);
            }
        }
    }
}