using System;

namespace Strata.Base.Internal
{
    public class SecurityUtils
    {

        #region  Declarations 
        private const string ENCRYPTION_KEY_SUFFIX = "SDT";
        private const int KEY_SIZE_BYTES = 32; // 256 bits for AES-256
        #endregion

        #region  Methods 

        private static string PadKey(string key)
        {
            if (key is null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            string paddedKey = key + ENCRYPTION_KEY_SUFFIX;
            if (paddedKey.Length < KEY_SIZE_BYTES)
            {
                paddedKey = paddedKey.PadRight(KEY_SIZE_BYTES, 'X');
            }
            else if (paddedKey.Length > KEY_SIZE_BYTES)
            {
                paddedKey = paddedKey.Substring(0, KEY_SIZE_BYTES);
            }
            return paddedKey;
        }

        public static string EncryptValue(string value, string key)
        {
            if (value is null)
            {
                return null;
            }

            if (string.IsNullOrEmpty(value))
            {
                return string.Empty;
            }

            if (key is null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            // Create encryptor with default IV
            var encryption = new EncryptionUtils.SymmetricEncryptor(EncryptionUtils.SymmetricEncryptor.Provider.AES);

            var result = encryption.Encrypt(new EncryptionUtils.Data(value), new EncryptionUtils.Data(PadKey(key)));
            return result.Base64;
        }

        public static string DecryptValue(string encryptedValue, string key)
        {
            if (encryptedValue is null)
            {
                return null;
            }

            if (string.IsNullOrEmpty(encryptedValue))
            {
                return string.Empty;
            }

            if (key is null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            var encryption = new EncryptionUtils.SymmetricEncryptor(EncryptionUtils.SymmetricEncryptor.Provider.AES);

            // note EncryptValue returns Base64 string so we need to initialized encryptedData as Base64
            var encryptedData = new EncryptionUtils.Data();
            encryptedData.Base64 = encryptedValue;

            return encryption.Decrypt(encryptedData, new EncryptionUtils.Data(PadKey(key))).Text;
        }

        #endregion

    }
}