using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class TrainService_DoubleVerification : System.Web.UI.Page
{
    string InputRequest, ReqAmount, BankTxnId, ReservationId;
    string[] arryStr = null;
    protected void Page_Load(object sender, EventArgs e)
    {
      
        if (Request.Form["encdata"] != null)
        {
            InputRequest = Request.Form["encdata"].ToString().Split(',')[0];
            InsertLog("DoubleRequest", InputRequest);
            string strAfterDecryption = DecryptStringFromBytes_Aes(ParseHex(InputRequest), "abfb7c8d48dfc4f1ce7ed92a44989f25", "232fcfdc2e2b4767");
            if (!strAfterDecryption.ToLower().Contains("merchantCode="))
            {
                strAfterDecryption = strAfterDecryption.Insert(0, "merchantCode=CRI");
            }
            //merchantCode=CRIS|reservationId=1100012345|txnAmount=458.00|currencyType=INR|appCode=BOOKING|pymtMode=Internet|txnDate=20111206|securityId=CRIS|RU=https://localhost:8080/eticketing/BankResponse|checkSum=1EF7C9AA4C9CF912C1539AE332E997E15019E40010A59363064C9C308EA13873
            InsertLog("DoubleReqDecrypt", strAfterDecryption);
            try
            {
                NameValueCollection ResponseString = new NameValueCollection();
                arryStr = strAfterDecryption.Split('|');
                for (Int16 i = 0; i <= arryStr.Length - 1; i++)
                {
                    string[] ArrString = arryStr[i].ToString().Split('=');
                    ResponseString.Add(ArrString[0], ArrString[1]);
                }
                ReqAmount = Convert.ToString(ResponseString["txnAmount"]);
                BankTxnId = Convert.ToString(ResponseString["bankTxnId"]).Trim();
                ReservationId = Convert.ToString(ResponseString["reservationId"]);
                if (ReservationId.ToLower() == "null") ReservationId = "";
                SqlParameter[] warlock = new SqlParameter[] { new SqlParameter("@reservationId", ReservationId), new SqlParameter("@bankTxnId", BankTxnId), new SqlParameter("@ReqAmount", ReqAmount), new SqlParameter("@Result", SqlDbType.VarChar, 100) };
                warlock[3].Direction = ParameterDirection.Output;
                SqlHelper.ExecuteNonQuery(SqlHelper.mainConnectionString, CommandType.StoredProcedure, "Doubleverification", warlock);
                string result = Convert.ToString(warlock[3].Value);
                if (result != "failed")
                {
                    //reservationId=104433|bankTxnId=IG01439494|txnAmount=1|status=0|statusDesc=Success|checkSum=C8166A2C4626ED03BF4918020D540AC3FCCD75F8BF393BAC61EB6A0D1F3191A8
        string ResponseData = "merchantCode=CRISVENUS|reservationId=" + result + "|bankTxnId= " + BankTxnId + "|txnAmount=" + ReqAmount + "|status=Success|statusDesc=Completed successfully";
                    string checksum = GenerateCheckSum(ResponseData);
                    ResponseData += "|checkSum=" + checksum;
                    InsertLog("DoubleVeriResD", ResponseData);
                    string _encResponseString = EncryptAPP(ResponseData, "abfb7c8d48dfc4f1ce7ed92a44989f25", "232fcfdc2e2b4767");
                    Response.Write(_encResponseString);
                    return;
                }
                else
                {
      string ResponseData = "merchantCode=CRISVENUS|reservationId=" + ReservationId + "|bankTxnId= " + BankTxnId + "|txnAmount=" + ReqAmount + "|status=Failure|statusDesc=Failure";
                    string checksum = GenerateCheckSum(ResponseData);
                    ResponseData += "|checkSum=" + checksum;
                    InsertLog("DoubleVeriResD", ResponseData);
                    string _encResponseString = EncryptAPP(ResponseData, "abfb7c8d48dfc4f1ce7ed92a44989f25", "232fcfdc2e2b4767");
                    Response.Write(_encResponseString);
                    return;
                }
                // }
            }
            catch (Exception ex)
            {
            }
        }
    }
    public string EncryptAPP(string textToEncrypt, string key, string ivString)
    {
        RijndaelManaged rijndaelCipher = new RijndaelManaged();
        rijndaelCipher.Mode = CipherMode.CBC;
        rijndaelCipher.Padding = PaddingMode.PKCS7;

        rijndaelCipher.KeySize = 0x80;
        rijndaelCipher.BlockSize = 0x80;
        byte[] pwdBytes = Encoding.UTF8.GetBytes(key);
        byte[] keyBytes = new byte[32];
        int len = pwdBytes.Length;
        if (len > keyBytes.Length)
        {
            len = keyBytes.Length;
        }
        Array.Copy(pwdBytes, keyBytes, len);
        byte[] iv = Encoding.UTF8.GetBytes(ivString);
        rijndaelCipher.Key = keyBytes;
        rijndaelCipher.IV = iv;
        ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
        byte[] plainText = Encoding.UTF8.GetBytes(textToEncrypt);
        string hexString = BitConverter.ToString(transform.TransformFinalBlock(plainText, 0, plainText.Length));
        hexString = hexString.Replace("-", "");
        return hexString;
    }
    public byte[] ParseHex(string hex)
    {
        int offset = hex.StartsWith("0x") ? 2 : 0;
        if ((hex.Length % 2) != 0)
        {
            throw new ArgumentException("Invalid length: " + hex.Length);
        }
        byte[] ret = new byte[(hex.Length - offset) / 2];

        for (int i = 0; i < ret.Length; i++)
        {
            ret[i] = (byte)((ParseNybble(hex[offset]) << 4)
                             | ParseNybble(hex[offset + 1]));
            offset += 2;
        }
        return ret;
    }

    public int ParseNybble(char c)
    {
        if (c >= '0' && c <= '9')
        {
            return c - '0';
        }
        if (c >= 'A' && c <= 'F')
        {
            return c - 'A' + 10;
        }
        if (c >= 'a' && c <= 'f')
        {
            return c - 'a' + 10;
        }
        throw new ArgumentException("Invalid hex digit: " + c);
    }
    public string DecryptStringFromBytes_Aes(byte[] input, string key, string ivString)
    {
        byte[] cipherTextCombined = input;
        byte[] Key;
        byte[] IV;
        IV = Encoding.UTF8.GetBytes(ivString);
        Key = Encoding.UTF8.GetBytes(key);
        string plaintext = null;

        using (Aes aesAlg = Aes.Create())
        {
            aesAlg.Key = Key;
            byte[] cipherText = new byte[cipherTextCombined.Length - IV.Length];
            Array.Copy(cipherTextCombined, IV, IV.Length);
            Array.Copy(cipherTextCombined, IV.Length, cipherText, 0, cipherText.Length);
            aesAlg.IV = IV;
            aesAlg.Mode = CipherMode.CBC;
            // Create a decrytor to perform the stream transform.
            ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
            // Create the streams used for decryption. 
            using (var msDecrypt = new MemoryStream(cipherText))
            {
                using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (var srDecrypt = new StreamReader(csDecrypt))
                    {
                        plaintext = srDecrypt.ReadToEnd();
                    }
                }
            }

        }
        return plaintext;
    }
    public void InsertLog(string ServiceName, string Log)
    {
        SqlParameter[] warlock = new SqlParameter[]
        {
            new SqlParameter("@ServiceName",ServiceName),
            new SqlParameter("@LogData",Log)
        };
        int a = SqlHelper.ExecuteNonQuery(SqlHelper.mainConnectionString, CommandType.StoredProcedure, "Insert_Train_Log", warlock);
    }
    public static string GenerateCheckSum(string text)
    {
        UTF8Encoding encoder = new UTF8Encoding();

        byte[] hashValue = null;
        byte[] message = encoder.GetBytes(text);

        SHA256Managed hashString = new SHA256Managed();
        string hex = "";

        hashValue = hashString.ComputeHash(message);
        foreach (byte x in hashValue)
        {
            hex += String.Format("{0:x2}", x);
        }
        return hex.ToUpper();
    }
}