using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;

namespace Apewer.Internals
{

    internal class Aes128Helper
    {

        private static RijndaelManaged Provider(byte[] argkey, byte[] argvector)
        {
            var vkey = argkey;
            if (vkey == null) vkey = new byte[0];
            if (vkey.Length != 16) vkey = HashHelper.MD5(vkey);

            var viv = argvector;
            if (viv == null) viv = new byte[0];
            if (viv.Length != 16) viv = HashHelper.MD5(viv);

            //vkey = Aes256Fill(argkey);
            //viv = Aes256Fill(argvector);

            var vp = new RijndaelManaged();
            vp.Key = vkey;
            vp.IV = viv;
            vp.Mode = CipherMode.CBC;
            vp.Padding = PaddingMode.PKCS7;
            return vp;
        }

        /// <summary>对数据进行 AES-128 加密。<para>若密钥不为 128 位则以密钥 MD5 作为密钥。若向量不为 128 位则与密钥相同。</para></summary>
        private static byte[] Encrypt(byte[] argData)
        {
            return Encrypt(argData, null, null);
        }

        /// <summary>对数据进行 AES-128 加密。<para>若密钥不为 128 位则以密钥 MD5 作为密钥。若向量不为 128 位则与密钥相同。</para></summary>
        private static byte[] Encrypt(byte[] argData, byte[] argKey)
        {
            return Encrypt(argData, argKey, null);
        }

        /// <summary>对数据进行 AES-128 加密。<para>若密钥不为 128 位则以密钥 MD5 作为密钥。若向量不为 128 位则与密钥相同。</para></summary>
        private static byte[] Encrypt(byte[] argData, byte[] argKey, byte[] argVector)
        {
            if (argData == null) return argData;
            if (argData.Length == 0) return argData;
            var vresult = Constant.EmptyBytes;
            var vencryptor = Provider(argKey, argVector).CreateEncryptor();
            try
            {
                vresult = vencryptor.TransformFinalBlock(argData, 0, argData.Length);
            }
            catch { }
            vencryptor.Dispose();
            return vresult;
        }

        /// <summary>对数据进行 AES-128 解密。<para>若密钥不为 128 位则以密钥 MD5 作为密钥。若向量不为 128 位则与密钥相同。</para></summary>
        private static byte[] Decrypt(byte[] argdata)
        {
            return Decrypt(argdata, null, null);
        }

        /// <summary>对数据进行 AES-128 解密。<para>若密钥不为 128 位则以密钥 MD5 作为密钥。若向量不为 128 位则与密钥相同。</para></summary>
        private static byte[] Decrypt(byte[] argdata, byte[] argkey)
        {
            return Decrypt(argdata, argkey, null);
        }

        /// <summary>对数据进行 AES-128 解密。<para>若密钥不为 128 位则以密钥 MD5 作为密钥。若向量不为 128 位则与密钥相同。</para></summary>
        private static byte[] Decrypt(byte[] argdata, byte[] argkey, byte[] argvector)
        {
            if (argdata == null) return argdata;
            if (argdata.Length == 0) return argdata;
            var vresult = Constant.EmptyBytes;
            var vdecryptor = Provider(argkey, argvector).CreateDecryptor();
            try
            {
                vresult = vdecryptor.TransformFinalBlock(argdata, 0, argdata.Length);
            }
            catch { }
            vdecryptor.Dispose();
            return vresult;
        }

    }

}