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

namespace Apewer.Internals
{

    internal class Aes256Helper
    {

        private static byte[] Fill(byte[] argBytes)
        {
            const int MaxLength = 32;
            var result = new byte[MaxLength];
            if ((argBytes == null) || (argBytes.Length == 0))
            {
                for (int i = 0; i < MaxLength; i++) result[i] = 0;
                return result;
            }
            else
            {
                var rl = 0;
                while (true)
                {
                    for (int i = 0; i < argBytes.Length; i++)
                    {
                        if (rl >= MaxLength) return result;
                        result[rl] = argBytes[i];
                        rl += 1;
                    }
                }
            }
        }

        private static RijndaelManaged Provider(byte[] argKey)
        {
            var key = argKey ?? Constant.EmptyBytes; // AesFill(argKey);
            var p = new RijndaelManaged();
            p.Key = key;
            p.Mode = CipherMode.ECB;
            p.Padding = PaddingMode.PKCS7;
            return p;
        }

        public static byte[] Encrypt(byte[] argData)
        {
            return Encrypt(argData, null);
        }

        /// <summary>对数据进行 AES 加密。</summary>
        public static byte[] Encrypt(byte[] argPlain, byte[] argKey = null)
        {
            if (argPlain == null) return Constant.EmptyBytes;
            if (argPlain.Length == 0) return Constant.EmptyBytes;
            var rm = Provider(argKey);
            var result = new byte[0];
            var ct = rm.CreateEncryptor();
            try
            {
                result = ct.TransformFinalBlock(argPlain, 0, argPlain.Length);
            }
            catch { }
            return result;
        }

        public static byte[] Decrypt(byte[] argData)
        {
            return Decrypt(argData, null);
        }

        public static byte[] Decrypt(byte[] argCipher, byte[] argKey)
        {
            if (argCipher == null) return Constant.EmptyBytes;
            if (argCipher.Length == 0) return Constant.EmptyBytes;
            var rm = Provider(argKey);
            var result = new byte[0];
            var ct = rm.CreateDecryptor();
            try
            {
                result = ct.TransformFinalBlock(argCipher, 0, argCipher.Length);
            }
            catch { }
            ct.Dispose();
            return result;
        }

    }

}