using Microsoft.VisualStudio.TestTools.UnitTesting;
using Edge.Core.Parser.BinaryParser.Util;
using ShellChina_EPS_Project_CarPlatePay_EpsClient_App.MessageEntity;
using ShellChina_EPS_Project_CarPlatePay_EpsClient_App.MessageEntity.Base;
using ShellChina_EPS_Project_CarPlatePay_EpsClient_App.MessageEntity.Incoming;
using ShellChina_EPS_Project_CarPlatePay_EpsClient_App.MessageEntity.Outgoing;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ShellChina_EPS_Project_CarPlatePay_EpsClient_App_Test
{
    [TestClass]
    public class MessageUnitTest
    {
        public static bool ValueEquals(IEnumerable<byte> array1, IEnumerable<byte> array2)
        {
            if (array1 == null && array2 == null)
            {
                return true;
            }

            if ((array1 == null) || (array2 == null))
            {
                return false;
            }

            if (array1.Count() != array2.Count())
            {
                return false;
            }
            if (array1.Equals(array2))
            {
                return true;
            }
            else
            {
                for (int Index = 0; Index < array1.Count(); Index++)
                {
                    if (!Equals(array1.ElementAt(Index), array2.ElementAt(Index)))
                    {
                        return false;
                    }
                }
            }
            return true;
        }

        [TestMethod]
        public void MembershipInquiryRequest_Serialize_TestMethod1()
        {
            string carPlateNumber = "78912345";
            string terminalId = "88";
            var tpdu = "3333";
            int messageTypeIdentifier = 200;
            var msg = new MembershipInquiryRequest(carPlateNumber, terminalId);
            msg.TPDU = tpdu;
            msg.MessageTypeIdentifier = messageTypeIdentifier;
            //msg.BitMap = new List<byte>() { 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
            //msg.Content = new List<byte>() { 0x00, 0x00, 0x99,
            //    0x00, 0x08, 0x37, 0x38, 0x39, 0x31, 0x32, 0x33, 0x34, 0x35,
            //   0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x88 };
            //msg.Content = msg.Content.Count.GetBinBytes(2).Concat(msg.MessageTypeIdentifier.GetBCDBytes(4)).Concat(msg.BitMap).ToList();
            var parser
                = new ShellChina_EPS_Project_CarPlatePay_EpsClient_App.Parser();
            var actual = parser.Serialize(msg);
            var expect = tpdu.PadLeft(10, '0').ToBCD()
                .Concat(messageTypeIdentifier.GetBCDBytes(2))
                .Concat(BitMapHelper.CreateMap(3, 34, 41))
                //.Concat(new List<byte>() { 0x08, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, }
                .Concat(020031.GetBCDBytes(3))
                .Concat(carPlateNumber.Length.GetBCDBytes(2)).Concat(Encoding.ASCII.GetBytes(carPlateNumber))
                .Concat(Encoding.ASCII.GetBytes(terminalId.PadLeft(12, '0')));

            expect = (actual.Length - 2).GetBinBytes(2).Concat(expect).ToList();
            Assert.AreEqual(true, ValueEquals(actual, expect),
                    "expect: \r\n" + expect.Select(e => e.ToString("X2")).Aggregate((acc, n) => acc + " " + n)
                    + "\r\n actual: \r\n" + actual.Select(e => e.ToString("X2")).Aggregate((acc, n) => acc + " " + n));
        }

        [TestMethod]
        public void MembershipInquiryRequest_Serialize_TestMethod2()
        {
            string carPlateNumber = "浙78912345";
            string terminalId = "88";
            var tpdu = "3333";
            int messageTypeIdentifier = 200;
            var msg = new MembershipInquiryRequest(carPlateNumber, terminalId);
            msg.TPDU = tpdu;
            msg.MessageTypeIdentifier = messageTypeIdentifier;
            //msg.BitMap = new List<byte>() { 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
            //msg.Content = new List<byte>() { 0x00, 0x00, 0x99,
            //    0x00, 0x08, 0x37, 0x38, 0x39, 0x31, 0x32, 0x33, 0x34, 0x35,
            //   0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x88 };
            //msg.Content = msg.Content.Count.GetBinBytes(2).Concat(msg.MessageTypeIdentifier.GetBCDBytes(4)).Concat(msg.BitMap).ToList();
            var parser
                = new ShellChina_EPS_Project_CarPlatePay_EpsClient_App.Parser();
            var actual = parser.Serialize(msg);
            var expect = tpdu.PadLeft(10, '0').ToBCD()
                .Concat(messageTypeIdentifier.GetBCDBytes(2))
                .Concat(BitMapHelper.CreateMap(3, 34, 41))
                .Concat(020031.GetBCDBytes(3))
                .Concat(carPlateNumber.Length.GetBCDBytes(2)).Concat(Encoding.UTF8.GetBytes(carPlateNumber))
                .Concat(Encoding.ASCII.GetBytes(terminalId.PadLeft(12, '0')));

            expect = (actual.Length - 2).GetBinBytes(2).Concat(expect).ToList();
            Assert.AreEqual(true, ValueEquals(actual, expect),
                    "expect: \r\n" + expect.Select(e => e.ToString("X2")).Aggregate((acc, n) => acc + " " + n)
                    + "\r\n actual: \r\n" + actual.Select(e => e.ToString("X2")).Aggregate((acc, n) => acc + " " + n));
        }

        [TestMethod]
        public void MembershipInquiryRequest_Serialize_TestMethod3()
        {
            string carPlateNumber = "浙BD912345";
            string terminalId = "33232388";
            var tpdu = "3333999";
            int messageTypeIdentifier = 200;
            var msg = new MembershipInquiryRequest(carPlateNumber, terminalId);
            msg.TPDU = tpdu;
            msg.MessageTypeIdentifier = messageTypeIdentifier;
            //msg.BitMap = new List<byte>() { 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
            //msg.Content = new List<byte>() { 0x00, 0x00, 0x99,
            //    0x00, 0x08, 0x37, 0x38, 0x39, 0x31, 0x32, 0x33, 0x34, 0x35,
            //   0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x88 };
            //msg.Content = msg.Content.Count.GetBinBytes(2).Concat(msg.MessageTypeIdentifier.GetBCDBytes(4)).Concat(msg.BitMap).ToList();
            var parser
                = new ShellChina_EPS_Project_CarPlatePay_EpsClient_App.Parser();
            var actual = parser.Serialize(msg);
            var expect = tpdu.PadLeft(10, '0').ToBCD()
                .Concat(messageTypeIdentifier.GetBCDBytes(2))
                .Concat(BitMapHelper.CreateMap(3, 34, 41))
                //.Concat(new List<byte>() { 0x08, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, }
                .Concat(020031.GetBCDBytes(3))
                .Concat(carPlateNumber.Length.GetBCDBytes(2)).Concat(Encoding.UTF8.GetBytes(carPlateNumber))
                .Concat(Encoding.ASCII.GetBytes(terminalId.PadLeft(12, '0')));

            expect = (actual.Length - 2).GetBinBytes(2).Concat(expect).ToList();
            Assert.AreEqual(true, ValueEquals(actual, expect),
                    "expect: \r\n" + expect.Select(e => e.ToString("X2")).Aggregate((acc, n) => acc + " " + n)
                    + "\r\n actual: \r\n" + actual.Select(e => e.ToString("X2")).Aggregate((acc, n) => acc + " " + n));
        }

        [TestMethod]
        public void MembershipInquiryRequest_Serialize_TestMethod4()
        {
            string carPlateNumber = "12浙BD912345";
            string terminalId = "3433232388";
            var tpdu = "3333999";
            int messageTypeIdentifier = 200;
            var msg = new MembershipInquiryRequest(carPlateNumber, terminalId);
            msg.TPDU = tpdu;
            msg.MessageTypeIdentifier = messageTypeIdentifier;
            //msg.BitMap = new List<byte>() { 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
            //msg.Content = new List<byte>() { 0x00, 0x00, 0x99,
            //    0x00, 0x08, 0x37, 0x38, 0x39, 0x31, 0x32, 0x33, 0x34, 0x35,
            //   0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x88 };
            //msg.Content = msg.Content.Count.GetBinBytes(2).Concat(msg.MessageTypeIdentifier.GetBCDBytes(4)).Concat(msg.BitMap).ToList();
            var parser
                = new ShellChina_EPS_Project_CarPlatePay_EpsClient_App.Parser();
            var actual = parser.Serialize(msg);
            var expect = tpdu.PadLeft(10, '0').ToBCD()
                .Concat(messageTypeIdentifier.GetBCDBytes(2))
                .Concat(BitMapHelper.CreateMap(3, 34, 41))
                //.Concat(new List<byte>() { 0x08, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, }
                .Concat(020031.GetBCDBytes(3))
                .Concat(carPlateNumber.Length.GetBCDBytes(2)).Concat(Encoding.UTF8.GetBytes(carPlateNumber))
                .Concat(Encoding.ASCII.GetBytes(terminalId.PadLeft(12, '0')));

            expect = (actual.Length - 2).GetBinBytes(2).Concat(expect).ToList();
            Assert.AreEqual(true, ValueEquals(actual, expect),
                    "expect: \r\n" + expect.Select(e => e.ToString("X2")).Aggregate((acc, n) => acc + " " + n)
                    + "\r\n actual: \r\n" + actual.Select(e => e.ToString("X2")).Aggregate((acc, n) => acc + " " + n));
        }

        [TestMethod]
        public void MembershipInquiryResponse_Deserialize_TestMethod1()
        {
            var parser = new ShellChina_EPS_Project_CarPlatePay_EpsClient_App.Parser();
            var raw = new byte[] {
                //报文长度	b2	长度位为2个字节binary格式数字
                0x00, 0x48,
                //TPDU	n10	TPDU为10位数字,报文中以5字节BCD码表示,本接口对TPDU内容没有特殊要求,终端中按应用的需求配置为固定的TPDU即可,如“6000300000”
                0x00, 0x03, 0x33, 0x39, 0x99,
                //报文类型标识	n4	MTI为消息类型标识(Message type identifier的简写),4位数字,报文中以2字节BCD码表示
                0x02, 0x10,
                //位图	b8	本接口规范仅使用8个字节基本位图,不使用扩展位图
                0x20,0x10,0x01,0x00,0x42,0x80,0x00,0x00,
                //P-3, 3 bytes
                0x02, 0x00, 0x31,
                //P-12,9 bytes
                0x31, 0x30, 0x30, 0x30, 0x31, 0x39, 0x00, 0x00, 0x00,
                //P-24, 20 bytes
                0x32, 0x33, 0x34, 0x32, 0x33, 0x32, 0x33, 0x34, 0x32, 0x33, 0x32, 0x33, 0x34,0x32, 0x33,0x32, 0x33, 0x34,0x32, 0x33,
                //P-34, 20 bytes
                0x00,0x06, 0x41,0x42,0x43,0x31,0x32,0x33,
                //P-39,  5 bytes
                0x32, 0x33, 0x34,0x32, 0x33,
                //P-41,
                0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32
            };
            var response = parser.Deserialize(raw) as MembershipInquiryResponse;
            Assert.AreEqual(true, response.P_3_处理码 == 020031);
            Assert.AreEqual(true, response.P_12_交易流水号.StartsWith("100019"));
            Assert.AreEqual(true, response.P_24_会员ID == "23423234232342323423");
            Assert.AreEqual(true, response.P_34_车牌号码 == "ABC123");
            Assert.AreEqual(true, response.P_39_交易响应码 == "23423");
            Assert.AreEqual(true, response.P_41_终端编号 == "123456789012");
            //00 39 00 03 33 39 99 02 00 08 00 00 00 04 02 00 00 00 2A 02 00 08 00 00 00 04 02 00 00 11 99 88 00 11 31 32 E6 B5 99 42 44 39 31 32 33 34 35 30 30 33 34 33 33 32 33 32 33 38 38
            //parser.Deserialize()
        }

        [TestMethod]
        public void MembershipInquiryResponse_Deserialize_TestMethod2()
        {
            var parser = new ShellChina_EPS_Project_CarPlatePay_EpsClient_App.Parser();
            var raw = "0048600003000002102010010042800000020031313030303139000000373030343930303035393438303036313031300000064142433132333030303030313233343536373839303132".ToBytes();
            var response = parser.Deserialize(raw) as MembershipInquiryResponse;
            Assert.AreEqual(true, response.TPDU == "6000030000");
            Assert.AreEqual(true, response.MessageTypeIdentifier == 210);
            Assert.AreEqual(true, response.P_3_处理码 == 020031);
            Assert.AreEqual(true, response.P_12_交易流水号.StartsWith("100019"));
            Assert.AreEqual(true, response.P_24_会员ID.StartsWith("7004900059480061010"));
            Assert.AreEqual(true, response.P_34_车牌号码 == "ABC123");
            Assert.AreEqual(true, response.P_39_交易响应码 == "00000");
            Assert.AreEqual(true, response.P_41_终端编号 == "123456789012");
            Assert.AreEqual(true, string.IsNullOrEmpty(response.P_40_错误信息));
            //00 39 00 03 33 39 99 02 00 08 00 00 00 04 02 00 00 00 2A 02 00 08 00 00 00 04 02 00 00 11 99 88 00 11 31 32 E6 B5 99 42 44 39 31 32 33 34 35 30 30 33 34 33 33 32 33 32 33 38 38
            //parser.Deserialize()
        }

        [TestMethod]
        public void MembershipInquiryResponse_Deserialize_FailResponse_TestMethod3()
        {
            var parser = new ShellChina_EPS_Project_CarPlatePay_EpsClient_App.Parser();
            var raw = ("002a" +
                "6000030000" +
                "0210" +
                "2000000003000000" +
                "020031" +
                "3030303031" +
                "0017b2e9d1afbbe1d4b1d0c5cfa2caa7b0dc3a").ToBytes();
            var response = parser.Deserialize(raw) as MembershipInquiryResponse;
            Assert.AreEqual(true, response.TPDU == "6000030000");
            Assert.AreEqual(true, response.MessageTypeIdentifier == 210);
            Assert.AreEqual(true, response.P_3_处理码 == 020031);
            Assert.AreEqual(true, response.P_39_交易响应码 == "00001");
            Assert.AreEqual(true, response.P_40_错误信息 == Encoding.ASCII.GetString("b2e9d1afbbe1d4b1d0c5cfa2caa7b0dc3a".ToBytes()));
            //00 39 00 03 33 39 99 02 00 08 00 00 00 04 02 00 00 00 2A 02 00 08 00 00 00 04 02 00 00 11 99 88 00 11 31 32 E6 B5 99 42 44 39 31 32 33 34 35 30 30 33 34 33 33 32 33 32 33 38 38
            //parser.Deserialize()
        }















        [TestMethod]
        public void PaymentRequest_Serialize_TestMethod1()
        {
            decimal amount = 11119.99M;
            string epsSeqNo = "12345abc";
            int siteLevelNozzleId = 5;
            string membershipId = "19831111";
            string carPlateNumber = "12浙BD912345";
            string terminalId = "3433232388";
            var tpdu = "3333999";
            int messageTypeIdentifier = 200;
            var msg = new PaymentRequest(amount, epsSeqNo, siteLevelNozzleId, membershipId, carPlateNumber, terminalId);
            msg.TPDU = tpdu;
            msg.MessageTypeIdentifier = messageTypeIdentifier;
            //msg.BitMap = new List<byte>() { 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
            //msg.Content = new List<byte>() { 0x00, 0x00, 0x99,
            //    0x00, 0x08, 0x37, 0x38, 0x39, 0x31, 0x32, 0x33, 0x34, 0x35,
            //   0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x88 };
            //msg.Content = msg.Content.Count.GetBinBytes(2).Concat(msg.MessageTypeIdentifier.GetBCDBytes(4)).Concat(msg.BitMap).ToList();
            var parser
                = new ShellChina_EPS_Project_CarPlatePay_EpsClient_App.Parser();
            var actual = parser.Serialize(msg);
            var expect = tpdu.PadLeft(10, '0').ToBCD()
                .Concat(messageTypeIdentifier.GetBCDBytes(2))
                .Concat(BitMapHelper.CreateMap(3, 4, 12, 23, 24, 34, 41))
                //.Concat(new List<byte>() { 0x08, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, }
                .Concat(020032.GetBCDBytes(3))
                .Concat(((int)(amount * 100)).GetBCDBytes(6))
                .Concat(Encoding.ASCII.GetBytes(epsSeqNo.PadRight(9, '\0')))
                .Concat(Encoding.ASCII.GetBytes(siteLevelNozzleId.ToString().PadLeft(2, '0')))
                .Concat(Encoding.ASCII.GetBytes(membershipId.PadRight(20, '\0')))
                .Concat(carPlateNumber.Length.GetBCDBytes(2)).Concat(Encoding.UTF8.GetBytes(carPlateNumber))
                .Concat(Encoding.ASCII.GetBytes(terminalId.PadLeft(12, '0')));

            expect = (actual.Length - 2).GetBinBytes(2).Concat(expect).ToList();
            Assert.AreEqual(true, ValueEquals(actual, expect),
                    "expect: \r\n" + expect.Select(e => e.ToString("X2")).Aggregate((acc, n) => acc + " " + n)
                    + "\r\n actual: \r\n" + actual.Select(e => e.ToString("X2")).Aggregate((acc, n) => acc + " " + n));
        }

        [TestMethod]
        public void PaymentRequest_Serialize_TestMethod2()
        {
            decimal amount = 1.02M;
            string epsSeqNo = "100071   ";
            int siteLevelNozzleId = 3;
            string membershipId = "7004900059480061010 ";
            string carPlateNumber = "ABC123";
            string terminalId = "123456789012";
            var tpdu = "6000030000";
            int messageTypeIdentifier = 200;
            var msg = new PaymentRequest(amount, epsSeqNo, siteLevelNozzleId, membershipId, carPlateNumber, terminalId);
            msg.TPDU = tpdu;
            msg.MessageTypeIdentifier = messageTypeIdentifier;
            //msg.BitMap = new List<byte>() { 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
            //msg.Content = new List<byte>() { 0x00, 0x00, 0x99,
            //    0x00, 0x08, 0x37, 0x38, 0x39, 0x31, 0x32, 0x33, 0x34, 0x35,
            //   0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x88 };
            //msg.Content = msg.Content.Count.GetBinBytes(2).Concat(msg.MessageTypeIdentifier.GetBCDBytes(4)).Concat(msg.BitMap).ToList();
            var parser
                = new ShellChina_EPS_Project_CarPlatePay_EpsClient_App.Parser();
            var actual = parser.Serialize(msg);
            var expect = tpdu.PadLeft(10, '0').ToBCD()
                .Concat(messageTypeIdentifier.GetBCDBytes(2))
                .Concat(BitMapHelper.CreateMap(3, 4, 12, 23, 24, 34, 41))
                //.Concat(new List<byte>() { 0x08, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, }
                .Concat(020032.GetBCDBytes(3))
                .Concat(((int)(amount * 100)).GetBCDBytes(6))
                .Concat(Encoding.ASCII.GetBytes(epsSeqNo.PadRight(9, '\0')))
                .Concat(Encoding.ASCII.GetBytes(siteLevelNozzleId.ToString().PadLeft(2, '0')))
                .Concat(Encoding.ASCII.GetBytes(membershipId.PadRight(20, '\0')))
                .Concat(carPlateNumber.Length.GetBCDBytes(2)).Concat(Encoding.UTF8.GetBytes(carPlateNumber))
                .Concat(Encoding.ASCII.GetBytes(terminalId.PadLeft(12, '0')));

            expect = (actual.Length - 2).GetBinBytes(2).Concat(expect).ToList();
            Assert.AreEqual(true, ValueEquals(actual, expect),
                    "expect: \r\n" + expect.Select(e => e.ToString("X2")).Aggregate((acc, n) => acc + " " + n)
                    + "\r\n actual: \r\n" + actual.Select(e => e.ToString("X2")).Aggregate((acc, n) => acc + " " + n));
        }

        [TestMethod]
        public void PaymentRequest_Serialize_TestMethod3()
        {
            decimal amount = 1.02M;
            string epsSeqNo = "100071";
            int siteLevelNozzleId = 3;
            string membershipId = "7004900059480061010";
            string carPlateNumber = "ABC123";
            string terminalId = "123456789012";
            var tpdu = "6000030000";
            int messageTypeIdentifier = 200;
            var msg = new PaymentRequest(amount, epsSeqNo, siteLevelNozzleId, membershipId, carPlateNumber, terminalId);
            msg.TPDU = tpdu;
            msg.MessageTypeIdentifier = messageTypeIdentifier;
            //msg.BitMap = new List<byte>() { 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
            //msg.Content = new List<byte>() { 0x00, 0x00, 0x99,
            //    0x00, 0x08, 0x37, 0x38, 0x39, 0x31, 0x32, 0x33, 0x34, 0x35,
            //   0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x88 };
            //msg.Content = msg.Content.Count.GetBinBytes(2).Concat(msg.MessageTypeIdentifier.GetBCDBytes(4)).Concat(msg.BitMap).ToList();
            var parser
                = new ShellChina_EPS_Project_CarPlatePay_EpsClient_App.Parser();
            var actual = parser.Serialize(msg);
            var expect = tpdu.PadLeft(10, '0').ToBCD()
                .Concat(messageTypeIdentifier.GetBCDBytes(2))
                .Concat(BitMapHelper.CreateMap(3, 4, 12, 23, 24, 34, 41))
                //.Concat(new List<byte>() { 0x08, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, }
                .Concat(020032.GetBCDBytes(3))
                .Concat(((int)(amount * 100)).GetBCDBytes(6))
                .Concat(Encoding.ASCII.GetBytes(epsSeqNo.PadRight(9, '\0')))
                .Concat(Encoding.ASCII.GetBytes(siteLevelNozzleId.ToString().PadLeft(2, '0')))
                .Concat(Encoding.ASCII.GetBytes(membershipId.PadRight(20, '\0')))
                .Concat(carPlateNumber.Length.GetBCDBytes(2)).Concat(Encoding.UTF8.GetBytes(carPlateNumber))
                .Concat(Encoding.ASCII.GetBytes(terminalId.PadLeft(12, '0')));

            expect = (actual.Length - 2).GetBinBytes(2).Concat(expect).ToList();
            Assert.AreEqual(true, ValueEquals(actual, expect),
                    "expect: \r\n" + expect.Select(e => e.ToString("X2")).Aggregate((acc, n) => acc + " " + n)
                    + "\r\n actual: \r\n" + actual.Select(e => e.ToString("X2")).Aggregate((acc, n) => acc + " " + n));
        }

        [TestMethod]
        public void PaymentRequest_Serialize_TestMethod4()
        {
            decimal amount = 1.02M;
            string epsSeqNo = "100071";
            int siteLevelNozzleId = 3;
            string membershipId = "7004900059480061010";
            string carPlateNumber = "ABC123";
            string terminalId = "123456789012";
            var tpdu = "6000030000";
            int messageTypeIdentifier = 200;
            var msg = new PaymentRequest(amount, epsSeqNo, siteLevelNozzleId, membershipId, carPlateNumber, terminalId);
            msg.TPDU = tpdu;
            msg.MessageTypeIdentifier = messageTypeIdentifier;
            //msg.BitMap = new List<byte>() { 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
            //msg.Content = new List<byte>() { 0x00, 0x00, 0x99,
            //    0x00, 0x08, 0x37, 0x38, 0x39, 0x31, 0x32, 0x33, 0x34, 0x35,
            //   0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x88 };
            //msg.Content = msg.Content.Count.GetBinBytes(2).Concat(msg.MessageTypeIdentifier.GetBCDBytes(4)).Concat(msg.BitMap).ToList();
            var parser
                = new ShellChina_EPS_Project_CarPlatePay_EpsClient_App.Parser();
            var actual = parser.Serialize(msg);
            // from real system log
            var expect = "600003000002003010030040800000020032000000000102313030303731000000303337303034393030303539343830303631303130000006414243313233313233343536373839303132".ToBytes();

            expect = (expect.Length).GetBinBytes(2).Concat(expect).ToArray();
            Assert.AreEqual(true, ValueEquals(actual, expect),
                    "expect: \r\n" + expect.Select(e => e.ToString("X2")).Aggregate((acc, n) => acc + " " + n)
                    + "\r\n actual: \r\n" + actual.Select(e => e.ToString("X2")).Aggregate((acc, n) => acc + " " + n));
        }

        [TestMethod]
        public void PaymentResponse_Deserialize_TestMethod1()
        {
            var parser = new ShellChina_EPS_Project_CarPlatePay_EpsClient_App.Parser();
            var raw = new byte[] {
                //报文长度	b2	长度位为2个字节binary格式数字
                0x00, 0x48,
                //TPDU	n10	TPDU为10位数字,报文中以5字节BCD码表示,本接口对TPDU内容没有特殊要求,终端中按应用的需求配置为固定的TPDU即可,如“6000300000”
                0x00, 0x03, 0x33, 0x39, 0x99,
                //报文类型标识	n4	MTI为消息类型标识(Message type identifier的简写),4位数字,报文中以2字节BCD码表示
                0x02, 0x10,
                //位图	b8	本接口规范仅使用8个字节基本位图,不使用扩展位图, field 3,4,5,7,12,39
                0x3a,0x10,0x00,0x00,0x02,0x00,0x00,0x00,
                //P-3, 3 bytes
                0x02, 0x00, 0x32,
                //P-4, 6 bytes, should pay amount
                0x00, 0x00, 0x00,0x00,0x00,0x78,
                //P-5, 6 bytes, actual pay amount
                0x00, 0x00, 0x00,0x00,0x00,0x78,
                //P-7, 7 bytes, datetime
                0x20,0x18,0x11,0x23,0x21,0x11,0x10,
                //P-12,9 bytes
                0x31, 0x30, 0x30, 0x30, 0x31, 0x39, 0x00, 0x00, 0x00,
                //P-39,  5 bytes
                0x32, 0x33, 0x34,0x32, 0x33,
            };
            var response = parser.Deserialize(raw) as PaymentResponse;
            Assert.AreEqual(true, response.P_3_处理码 == 020032);
            Assert.AreEqual(true, response.P_4_交易金额 == 0.78M);
            Assert.AreEqual(true, response.P_5_实付金额 == 0.78M);
            Assert.AreEqual(true, response.P_7_交易时间.Equals(new System.DateTime(2018, 11, 23, 21, 11, 10)));

            Assert.AreEqual(true, response.P_12_交易流水号.StartsWith("100019"));
            Assert.AreEqual(true, response.P_39_交易响应码 == "23423");
            //00 39 00 03 33 39 99 02 00 08 00 00 00 04 02 00 00 00 2A 02 00 08 00 00 00 04 02 00 00 11 99 88 00 11 31 32 E6 B5 99 42 44 39 31 32 33 34 35 30 30 33 34 33 33 32 33 32 33 38 38
            //parser.Deserialize()
        }

        [TestMethod]
        public void PaymentResponse_Deserialize_TestMethod2()
        {
            var parser = new ShellChina_EPS_Project_CarPlatePay_EpsClient_App.Parser();
            // from real system log.
            var raw = "0033600003000002103a10000002000000020032000000000078000000000078201811232111103130303037310000003030303030".ToBytes();
            var response = parser.Deserialize(raw) as PaymentResponse;
            Assert.AreEqual(true, response.TPDU == "6000030000");
            Assert.AreEqual(true, response.MessageTypeIdentifier == 210);
            Assert.AreEqual(true, response.P_3_处理码 == 020032);
            Assert.AreEqual(true, response.P_4_交易金额 == 0.78M);
            Assert.AreEqual(true, response.P_5_实付金额 == 0.78M);
            Assert.AreEqual(true, response.P_7_交易时间.Equals(new System.DateTime(2018, 11, 23, 21, 11, 10)));
            Assert.AreEqual(true, response.P_12_交易流水号.StartsWith("100071"));
            Assert.AreEqual(true, response.P_39_交易响应码 == "00000");
            Assert.AreEqual(true, string.IsNullOrEmpty(response.P_40_错误信息));
            //00 39 00 03 33 39 99 02 00 08 00 00 00 04 02 00 00 00 2A 02 00 08 00 00 00 04 02 00 00 11 99 88 00 11 31 32 E6 B5 99 42 44 39 31 32 33 34 35 30 30 33 34 33 33 32 33 32 33 38 38
            //parser.Deserialize()
        }

        [TestMethod]
        public void PaymentResponse_Deserialize_FailResponse_TestMethod3()
        {
            var parser = new ShellChina_EPS_Project_CarPlatePay_EpsClient_App.Parser();
            var raw = ("0029" +
                "6000030000" +
                "0210" +
                "20 00 00 00 03 000000" +
                "020032" +
                "3030303031" +
                "0016c3bbd3d0bdbbd2d7d0e8d2aacadcc0ed").ToBytes();
            var response = parser.Deserialize(raw) as PaymentResponse;
            Assert.AreEqual(true, response.TPDU == "6000030000");
            Assert.AreEqual(true, response.MessageTypeIdentifier == 210);
            Assert.AreEqual(true, response.P_3_处理码 == 020032);
            Assert.AreEqual(true, response.P_39_交易响应码 == "00001");
            Assert.AreEqual(true, response.P_40_错误信息 == Encoding.GetEncoding("GB2312").GetString("c3bbd3d0bdbbd2d7d0e8d2aacadcc0ed".ToBytes()));
            //00 39 00 03 33 39 99 02 00 08 00 00 00 04 02 00 00 00 2A 02 00 08 00 00 00 04 02 00 00 11 99 88 00 11 31 32 E6 B5 99 42 44 39 31 32 33 34 35 30 30 33 34 33 33 32 33 32 33 38 38
            //parser.Deserialize()
        }

        [TestMethod]
        public void PaymentResponse_Deserialize_TestMethod9()
        {
            var parser = new ShellChina_EPS_Project_CarPlatePay_EpsClient_App.Parser();
            // from real system log.
            var raw = ("003360000300000210" + "3a10400002000000" + "02003200000000007800000000007820181123211110313030303731000000" + "00033130393030303030").ToBytes();
            var response = parser.Deserialize(raw) as PaymentResponse;
            Assert.AreEqual(true, response.TPDU == "6000030000");
            Assert.AreEqual(true, response.MessageTypeIdentifier == 210);
            Assert.AreEqual(true, response.P_3_处理码 == 020032);
            Assert.AreEqual(true, response.P_4_交易金额 == 0.78M);
            Assert.AreEqual(true, response.P_5_实付金额 == 0.78M);
            Assert.AreEqual(true, response.P_7_交易时间.Equals(new System.DateTime(2018, 11, 23, 21, 11, 10)));
            Assert.AreEqual(true, response.P_12_交易流水号.StartsWith("100071"));
            Assert.AreEqual(true, response.P_18_商户订单号 == "109");
            Assert.AreEqual(true, response.P_39_交易响应码 == "00000");
            Assert.AreEqual(true, string.IsNullOrEmpty(response.P_40_错误信息));
            //00 39 00 03 33 39 99 02 00 08 00 00 00 04 02 00 00 00 2A 02 00 08 00 00 00 04 02 00 00 11 99 88 00 11 31 32 E6 B5 99 42 44 39 31 32 33 34 35 30 30 33 34 33 33 32 33 32 33 38 38
            //parser.Deserialize()
        }
    }
}