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

namespace Apewer.Internals
{

    internal class AesHelper
    {

        private static long AesSteam(ICryptoTransform argCT, Stream argInput, Stream argOutput)
        {
            long vcount = 0;
            var vcs = new CryptoStream(argOutput, argCT, CryptoStreamMode.Write);
            try
            {
                vcount = StreamHelper.Read(argInput, argOutput);
                vcs.FlushFinalBlock();
            }
            catch (Exception argException)
            {
                throw argException;
            }
            vcs.Dispose();
            return vcount;
        }

        /// <summary>对数据进行 AES 加密。</summary>
        public static byte[] AesEncrypt(byte[] argdata, byte[] argkey, byte[] argvector)
        {
            var vkey = (argkey == null) ? new byte[0] : argkey;

            RijndaelManaged vrm = new RijndaelManaged();
            vrm.KeySize = (argkey.Length <= 128) ? 128 : ((argkey.Length <= 192) ? 192 : 256);

            var viv = vrm.IV;
            var vr = Rijndael.Create();
            var vct = vr.CreateEncryptor(vkey, viv);
            var vinput = new MemoryStream(argdata);
            var voutput = new MemoryStream();
            AesSteam(vct, vinput, voutput);
            vinput.Dispose();
            var vresult = voutput.ToArray();
            voutput.Dispose();

            return vresult;
        }

        /// <summary>对数据进行 AES 解密。</summary>
        public static byte[] AesDecrypt(byte[] argdata, byte[] argkey, byte[] argvector)
        {
            var vkey = (argkey == null) ? new byte[0] : argkey;

            RijndaelManaged vrm = new RijndaelManaged();
            vrm.KeySize = (argkey.Length <= 128) ? 128 : ((argkey.Length <= 192) ? 192 : 256);

            var viv = vrm.IV;
            var vr = Rijndael.Create();
            var vct = vr.CreateDecryptor(vkey, viv);
            var vinput = new MemoryStream(argdata);
            var voutput = new MemoryStream();
            AesSteam(vct, vinput, voutput);
            vinput.Dispose();
            var vresult = voutput.ToArray();
            voutput.Dispose();

            return vresult;
        }

    }

}