using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

using System.Runtime.InteropServices;
using Cosmos.BaseFrame;
using Cosmos.UserFrame;

/*------------------------------------------------------------------------------------------------*/
// 설      명 : AES 암호화/복호화 
// 작  성  자 : 
// 변경  이력 : 
/*------------------------------------------------------------------------------------------------*/
namespace Cosmos.Common
{
    /// <summary>
    /// CommonAES 클래스를 통하여 AES - Base64 를 이용한 암호화/복호화 처리
    /// </summary>
    public class AES
    {
        /// <summary>
        /// 암호화 키 고정값("0001000100010001")
        /// </summary>
        //private static string STATIC_KEY = "0001000100010001";

        #region 가변키 암호화/복호화
        /// <summary>
        /// 가변키 암호화
        /// </summary>
        /// <param name="pPosNo">POS번호</param>
        /// <param name="pSysYmdhms">Tran번호</param>
        /// <param name="pPlainText">평문</param>
        /// <returns>암호화 실패하면 평문을 리턴</returns>
        public static string DynamicKeyEncrypt(string pPosNo, string pSysYmdhms, string pPlainText)
        {
            string sEncData = "", sDecData = "";
            try
            {
                if (pPlainText == "") return "";

                for(int i = 0;i < 10;i++)
                {
                    sEncData = UserLog.UserAES.DynamicKeyEncrypt(pPosNo, pSysYmdhms, pPlainText);
                    if(sEncData == pPlainText)
                    {
                        Thread.Sleep(100);
                        continue;
                    }
                    sDecData = UserLog.UserAES.DynamicKeyDecrypt(pPosNo, pSysYmdhms, sEncData);
                    if(sDecData == pPlainText)
                    {
                        Thread.Sleep(100);
                        continue;
                    }
                    if(i == 9)
                    {
                        UserLog.WriteLogFile(UserCom.LOG_ERROR, UserCom.ERROR_LEVEL, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                    "AES.DynamicKeyEncrypt()", "가변키 암호화 실패=>" + pPlainText);
                    }
                    break;
                }
            }
            catch { }
            return sEncData;
        }

        /// <summary>
        /// 가변키 암호화
        /// </summary>
        /// <param name="pPosNo">POS번호</param>
        /// <param name="pTranNo">Tran번호</param>
        /// <param name="pPlainText">평문</param>
        /// <returns>암호화 실패하면 평문을 리턴</returns>
        public static byte[] DynamicKeyEncrypt(string pPosNo, string pTranNo, byte[] pPlainText)
        {
            byte[] bytEncData = null, bytDecData = null;
            try
            {
                for(int i = 0;i < 10;i++)
                {
                    bytEncData = UserLog.UserAES.DynamicKeyEncrypt(pPosNo, pTranNo, pPlainText);
                    if(Encoding.Default.GetString(bytEncData, 0, bytEncData.Length) == Encoding.Default.GetString(pPlainText, 0, pPlainText.Length))
                    {
                        Thread.Sleep(100);
                        continue;
                    }
                    bytDecData = UserLog.UserAES.DynamicKeyDecrypt(pPosNo, pTranNo, bytEncData);
                    if(Encoding.Default.GetString(bytDecData, 0, bytDecData.Length) == Encoding.Default.GetString(pPlainText, 0, pPlainText.Length))
                    {
                        Thread.Sleep(100);
                        continue;
                    }
                    if(i == 9)
                    {
                        UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                    "AES.DynamicKeyEncrypt()", "가변키 암호화 실패=>" + Encoding.Default.GetString(pPlainText, 0, pPlainText.Length));
                    }
                    break;
                }
            }
            catch { }
            return bytEncData;
        }

        /// <summary>
        /// 가변키 복호화
        /// </summary>
        /// <param name="pPosNo">POS번호</param>
        /// <param name="pTranNo">Tran번호</param>
        /// <param name="pEncryptText">암호문</param>
        /// <returns>복호화 실패하면 암호문 리턴</returns>
        public static string DynamicKeyDecrypt(string pPosNo, string pTranNo, string pEncryptText)
        {
            string sEncData = "", sDecData = "";
            try
            {
                if (pEncryptText == "") return "";

                for (int i = 0; i < 10; i++)
                {
                    sDecData = UserLog.UserAES.DynamicKeyDecrypt(pPosNo, pTranNo, pEncryptText);
                    if (sDecData == pEncryptText)
                    {
                        Thread.Sleep(100);
                        continue;
                    }
                    sEncData = UserLog.UserAES.DynamicKeyEncrypt(pPosNo, pTranNo, sDecData);
                    if (sEncData != pEncryptText)
                    {
                        Thread.Sleep(100);
                        continue;
                    }
                    if (i == 9)
                    {
                        UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                    "AES.DynamicKeyDecrypt()", "가변키 복호화 실패=>" + pEncryptText);
                    }
                    break;
                }
            }
            catch { }
            return sDecData;
        }

        /// <summary>
        /// 가변키 복호화
        /// </summary>
        /// <param name="pPosNo">POS번호</param>
        /// <param name="pTranNo">Tran번호</param>
        /// <param name="pEncryptText">암호문</param>
        /// <returns>복호화 실패하면 암호문 리턴</returns>
        public static byte[] DynamicKeyDecrypt(string pPosNo, string pTranNo, byte[] pEncryptText)
        {
            byte[] bytEncData = null, bytDecData = null;
            try
            {
                for (int i = 0; i < 10; i++)
                {
                    bytDecData = UserLog.UserAES.DynamicKeyDecrypt(pPosNo, pTranNo, pEncryptText);
                    if (Encoding.Default.GetString(bytDecData, 0, bytDecData.Length) == Encoding.Default.GetString(pEncryptText, 0, pEncryptText.Length))
                    {
                        Thread.Sleep(100);
                        continue;
                    }
                    bytEncData = UserLog.UserAES.DynamicKeyEncrypt(pPosNo, pTranNo, bytDecData);
                    if (Encoding.Default.GetString(bytEncData, 0, bytEncData.Length) != Encoding.Default.GetString(pEncryptText, 0, pEncryptText.Length))
                    {
                        Thread.Sleep(100);
                        continue;
                    }
                    if (i == 9)
                    {
                        UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                    "AES.DynamicKeyDecrypt()", "가변키 복호화 오류=>" + Encoding.Default.GetString(pEncryptText, 0, pEncryptText.Length));
                    }
                    break;
                }
            }
            catch { }
            return bytDecData;
        }
        #endregion

        #region 고정키 암호화/복호화, 고정키 : 0001000100010001
        /// <summary>
        /// 고정키 암호화
        /// </summary>
        /// <param name="pPlainText">평문</param>
        /// <returns>암호화 실패하면 평문 리턴</returns>
        public static string StaticKeyEncrypt(string pPlainText)
        {
            string sEncData = "", sDecData = "";
            try
            {
                if (pPlainText == "") return "";

                for(int i = 0;i < 10;i++)
                {
                    sEncData = UserLog.UserAES.StaticKeyEncrypt(pPlainText);
                    if (sEncData == pPlainText)
                    {
                        Thread.Sleep(100);
                        continue;
                    }
                    sDecData = UserLog.UserAES.StaticKeyDecrypt(sEncData);
                    if (sDecData != pPlainText)
                    {
                        Thread.Sleep(100);
                        continue;
                    }
                    if (i == 9)
                    {
                        UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                        "AES.StaticKeyEncrypt()", "고정키 암호화 오류=>" + pPlainText);
                    }
                    break;
                }
            }
            catch { }
            return sEncData;
        }

        /// <summary>
        /// 고정키 복호화
        /// </summary>
        /// <param name="pEncryptText">암호문</param>
        /// <returns>복호화 실패하면 평문 리턴</returns>
        public static string StaticKeyDecrypt(string pEncryptText)
        {
            string sEncData = "", sDecData = "";
            try
            {
                if (pEncryptText == "") return "";

                for (int i = 0; i < 10; i++)
                {
                    sDecData = UserLog.UserAES.StaticKeyDecrypt(pEncryptText);
                    if (sDecData == pEncryptText)
                    {
                        Thread.Sleep(500);
                        continue;
                    }
                    sEncData = UserLog.UserAES.StaticKeyEncrypt(sDecData);
                    if (sEncData != pEncryptText)
                    {
                        Thread.Sleep(500);
                        continue;
                    }
                    if (i == 9)
                    {
                        UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                       "AES.StaticKeyDecrypt()", "고정키 복호화 오류=>" + pEncryptText);
                    }
                    break;
                }
            }
            catch { }
            return sDecData;
        }
        #endregion
    }
}
