// Copyright 2015 Tony Bai.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package cmpp_test

import (
	"fmt"
	"testing"

	"github.com/bigwhite/gocmpp"
	"github.com/bigwhite/gocmpp/utils"
)

var (
	sourceId               string   = "100201"
	destinationId          string   = "111112"
	nodesCount             uint8    = 0
	fwdMsgId               uint64   = 0x1
	msgFwdType             uint8    = 0
	fwdPkTotal             uint8    = 1
	fwdPkNumber            uint8    = 1
	fwdRegisteredDelivery  uint8    = 0
	fwdMsgLevel            uint8    = 1
	fwdServiceId           string   = "test"
	fwdFeeUserType         uint8    = 2
	fwdFeeTerminalId       string   = "13500002696"
	fwdFeeTerminalType     uint8    = 0
	fwdFeeTerminalUserType uint8    = 0
	fwdMsgFmt              uint8    = 8
	fwdMsgSrc              string   = "321321"
	fwdFeeType             string   = "02"
	fwdFeeCode             string   = "10"
	fwdValidTime           string   = "151115131555101+"
	fwdAtTime              string   = ""
	fwdSrcId               string   = "99998888"
	fwdSrcUserType         uint8    = 0
	fwdSrcType             uint8    = 0
	fwdDestUsrTl           uint8    = 1
	fwdDestId              []string = []string{"13500002696"}
	fwdDestTerminalType    uint8    = 0
	fwdDestUserType        uint8    = 0
	fwdUtf8Content                  = "测试gocmpp fwd"
	fwdMsgLength           uint8
	fwdMsgContent          string
)

func init() {
	var err error
	fwdMsgContent, err = cmpputils.Utf8ToUcs2(fwdUtf8Content)
	if err != nil {
		fmt.Println("utf8 to ucs2 transform err:", err)
		return
	}
	fwdMsgLength = uint8(len(fwdMsgContent))
}

func TestCmpp2FwdReqPktPack(t *testing.T) {
	p := &cmpp.Cmpp2FwdReqPkt{
		SourceId:           sourceId,
		DestinationId:      destinationId,
		NodesCount:         nodesCount,
		MsgFwdType:         msgFwdType,
		PkTotal:            fwdPkTotal,
		PkNumber:           fwdPkNumber,
		RegisteredDelivery: fwdRegisteredDelivery,
		MsgLevel:           fwdMsgLevel,
		ServiceId:          fwdServiceId,
		FeeUserType:        fwdFeeUserType,
		FeeTerminalId:      fwdFeeTerminalId,
		MsgFmt:             fwdMsgFmt,
		MsgSrc:             fwdMsgSrc,
		FeeType:            fwdFeeType,
		FeeCode:            fwdFeeCode,
		ValidTime:          fwdValidTime,
		AtTime:             fwdAtTime,
		SrcId:              fwdSrcId,
		DestUsrTl:          fwdDestUsrTl,
		DestId:             fwdDestId,
		MsgLength:          fwdMsgLength,
		MsgContent:         fwdMsgContent,
	}

	data, err := p.Pack(seqId)
	if err != nil {
		t.Fatal("Cmpp2FwdReqPkt pack error:", err)
	}

	if p.SeqId != seqId {
		t.Fatalf("After pack, seqId is %d, not equal to expected: %d\n", p.SeqId, seqId)
	}

	dataExpected := []byte{
		0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x17, 0x31, 0x30, 0x30, 0x32,
		0x30, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x02, 0x31, 0x33, 0x35, 0x30, 0x30, 0x30, 0x30, 0x32, 0x36, 0x39, 0x36, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x33, 0x32, 0x31, 0x33, 0x32, 0x31, 0x30,
		0x32, 0x31, 0x30, 0x00, 0x00, 0x00, 0x00, 0x31, 0x35, 0x31, 0x31, 0x31, 0x35, 0x31, 0x33, 0x31,
		0x35, 0x35, 0x35, 0x31, 0x30, 0x31, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x39, 0x39, 0x39, 0x38, 0x38, 0x38,
		0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x31,
		0x33, 0x35, 0x30, 0x30, 0x30, 0x30, 0x32, 0x36, 0x39, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x18, 0x6d, 0x4b, 0x8b, 0xd5, 0x00, 0x67, 0x00, 0x6f, 0x00, 0x63, 0x00,
		0x6d, 0x00, 0x70, 0x00, 0x70, 0x00, 0x20, 0x00, 0x66, 0x00, 0x77, 0x00, 0x64, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00,
	}

	l1 := len(data)
	l2 := len(dataExpected)
	if l1 != l2 {
		t.Fatalf("After pack, data length is %d, not equal to length expected: %d\n", l1, l2)
	}

	for i := 0; i < l1; i++ {
		if data[i] != dataExpected[i] {
			t.Fatalf("After pack, data[%d] is %x, not equal to dataExpected[%d]: %x\n", i, data[i], i, dataExpected[i])
		}
	}
}

func TestCmpp2FwdReqPktUnpack(t *testing.T) {
	data := []byte{
		0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x17, 0x31, 0x30, 0x30, 0x32,
		0x30, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x02, 0x31, 0x33, 0x35, 0x30, 0x30, 0x30, 0x30, 0x32, 0x36, 0x39, 0x36, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x33, 0x32, 0x31, 0x33, 0x32, 0x31, 0x30,
		0x32, 0x31, 0x30, 0x00, 0x00, 0x00, 0x00, 0x31, 0x35, 0x31, 0x31, 0x31, 0x35, 0x31, 0x33, 0x31,
		0x35, 0x35, 0x35, 0x31, 0x30, 0x31, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x39, 0x39, 0x39, 0x38, 0x38, 0x38,
		0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x31,
		0x33, 0x35, 0x30, 0x30, 0x30, 0x30, 0x32, 0x36, 0x39, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x18, 0x6d, 0x4b, 0x8b, 0xd5, 0x00, 0x67, 0x00, 0x6f, 0x00, 0x63, 0x00,
		0x6d, 0x00, 0x70, 0x00, 0x70, 0x00, 0x20, 0x00, 0x66, 0x00, 0x77, 0x00, 0x64, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00,
	}

	p := &cmpp.Cmpp2FwdReqPkt{}
	err := p.Unpack(data[8:])
	if err != nil {
		t.Fatal("Cmpp2FwdReqPkt unpack error:", err)
	}

	var resultSet = []struct {
		name          string
		value         interface{}
		expectedValue interface{}
	}{
		{"SeqId", p.SeqId, seqId},
		{"SourceId", p.SourceId, sourceId},
		{"DestinationId", p.DestinationId, destinationId},
		{"NodesCount", p.NodesCount, nodesCount},
		{"MsgFwdType", p.MsgFwdType, msgFwdType},
		{"MsgId", p.MsgId, uint64(0)},
		{"PkTotal", p.PkTotal, fwdPkTotal},
		{"PkNumber", p.PkNumber, fwdPkNumber},
		{"RegisteredDelivery", p.RegisteredDelivery, fwdRegisteredDelivery},
		{"MsgLevel", p.MsgLevel, fwdMsgLevel},
		{"ServiceId", p.ServiceId, fwdServiceId},
		{"FeeUserType", p.FeeUserType, fwdFeeUserType},
		{"FeeTerminalId", p.FeeTerminalId, fwdFeeTerminalId},
		{"MsgFmt", p.MsgFmt, fwdMsgFmt},
		{"MsgSrc", p.MsgSrc, fwdMsgSrc},
		{"FeeType", p.FeeType, fwdFeeType},
		{"FeeCode", p.FeeCode, fwdFeeCode},
		{"ValidTime", p.ValidTime, fwdValidTime},
		{"AtTime", p.AtTime, fwdAtTime},
		{"SrcId", p.SrcId, fwdSrcId},
		{"DestUsrTl", p.DestUsrTl, fwdDestUsrTl},
		{"DestId", p.DestId[0], fwdDestId[0]},
		{"MsgLength", p.MsgLength, fwdMsgLength},
		{"MsgContent", p.MsgContent, fwdMsgContent},
	}

	for _, r := range resultSet {
		if r.value != r.expectedValue {
			t.Fatalf("After unpack, %s in packet is %#v, not equal to the expected value: %#v\n", r.name, r.value, r.expectedValue)
		}
	}
}

func TestCmpp2FwdRspPktPack(t *testing.T) {
	p := &cmpp.Cmpp2FwdRspPkt{
		MsgId:    12878564852733378560, //0xb2, 0xb9, 0xda, 0x80, 0x00, 0x01, 0x00, 0x00
		PkTotal:  fwdPkTotal,
		PkNumber: fwdPkNumber,
		Result:   0,
	}

	data, err := p.Pack(seqId)
	if err != nil {
		t.Fatal("Cmpp2FwdRspPkt pack error:", err)
	}

	if p.SeqId != seqId {
		t.Fatalf("After pack, seqId is %d, not equal to expected: %d\n", p.SeqId, seqId)
	}

	dataExpected := []byte{
		0x00, 0x00, 0x00, 0x17, 0x80, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x17,
		0xb2, 0xb9, 0xda, 0x80, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00,
	}

	l1 := len(data)
	l2 := len(dataExpected)
	if l1 != l2 {
		t.Fatalf("After pack, data length is %d, not equal to length expected: %d\n", l1, l2)
	}

	for i := 0; i < l1; i++ {
		if data[i] != dataExpected[i] {
			t.Fatalf("After pack, data[%d] is %x, not equal to dataExpected[%d]: %x\n", i, data[i], i, dataExpected[i])
		}
	}
}

func TestCmpp2FwdRspPktUnpack(t *testing.T) {
	data := []byte{
		0x00, 0x00, 0x00, 0x17, 0x80, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x17,
		0xb2, 0xb9, 0xda, 0x80, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00,
	}

	p := &cmpp.Cmpp2FwdRspPkt{}
	err := p.Unpack(data[8:])
	if err != nil {
		t.Fatal("Cmpp2FwdRspPkt unpack error:", err)
	}

	if p.SeqId != seqId {
		t.Fatalf("After unpack, seqId in packet is %x, not equal to the expected value: %x\n", p.SeqId, seqId)
	}

	var msgId uint64 = 12878564852733378560 //0xb2, 0xb9, 0xda, 0x80, 0x00, 0x01, 0x00, 0x00
	if p.MsgId != msgId {
		t.Fatalf("After unpack, msgId in packet is %d, not equal to the expected value: %d\n", p.MsgId, msgId)
	}
	if p.PkTotal != 0x1 {
		t.Fatalf("After unpack, pktotal in packet is %d, not equal to the expected value: %d\n", p.Result, 0)
	}
	if p.PkNumber != 0x1 {
		t.Fatalf("After unpack, pktotal in packet is %d, not equal to the expected value: %d\n", p.Result, 0)
	}
	if p.Result != 0x0 {
		t.Fatalf("After unpack, result in packet is %d, not equal to the expected value: %d\n", p.Result, 0)
	}
}

func TestCmpp3FwdReqPktPack(t *testing.T) {
	p := &cmpp.Cmpp3FwdReqPkt{
		SourceId:            sourceId,
		DestinationId:       destinationId,
		NodesCount:          nodesCount,
		MsgFwdType:          msgFwdType,
		MsgId:               fwdMsgId,
		PkTotal:             fwdPkTotal,
		PkNumber:            fwdPkNumber,
		RegisteredDelivery:  fwdRegisteredDelivery,
		MsgLevel:            fwdMsgLevel,
		ServiceId:           fwdServiceId,
		FeeUserType:         fwdFeeUserType,
		FeeTerminalId:       fwdFeeTerminalId,
		FeeTerminalUserType: fwdFeeTerminalUserType,
		MsgFmt:              fwdMsgFmt,
		MsgSrc:              fwdMsgSrc,
		FeeType:             fwdFeeType,
		FeeCode:             fwdFeeCode,
		ValidTime:           fwdValidTime,
		AtTime:              fwdAtTime,
		SrcId:               fwdSrcId,
		SrcUserType:         fwdSrcUserType,
		SrcType:             fwdSrcType,
		DestUsrTl:           fwdDestUsrTl,
		DestId:              fwdDestId,
		DestUserType:        fwdDestUserType,
		MsgLength:           fwdMsgLength,
		MsgContent:          fwdMsgContent,
	}

	data, err := p.Pack(seqId)
	if err != nil {
		t.Fatal("Cmpp3FwdReqPkt pack error:", err)
	}

	if p.SeqId != seqId {
		t.Fatalf("After pack, seqId is %d, not equal to expected: %d\n", p.SeqId, seqId)
	}

	dataExpected := []byte{
		0x00, 0x00, 0x01, 0x35, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x17, 0x31, 0x30, 0x30, 0x32,
		0x30, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x02, 0x31, 0x33, 0x35, 0x30, 0x30, 0x30, 0x30, 0x32, 0x36, 0x39, 0x36, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x33, 0x32, 0x31, 0x33, 0x32, 0x31,
		0x30, 0x32, 0x31, 0x30, 0x00, 0x00, 0x00, 0x00, 0x31, 0x35, 0x31, 0x31, 0x31, 0x35, 0x31, 0x33,
		0x31, 0x35, 0x35, 0x35, 0x31, 0x30, 0x31, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x39, 0x39, 0x39, 0x38, 0x38,
		0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x01, 0x31, 0x33, 0x35, 0x30, 0x30, 0x30, 0x30, 0x32, 0x36, 0x39, 0x36, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x6d, 0x4b, 0x8b, 0xd5, 0x00, 0x67, 0x00,
		0x6f, 0x00, 0x63, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x70, 0x00, 0x20, 0x00, 0x66, 0x00, 0x77, 0x00,
		0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00,
	}

	l1 := len(data)
	l2 := len(dataExpected)
	if l1 != l2 {
		t.Fatalf("After pack, data length is %d, not equal to length expected: %d\n", l1, l2)
	}

	for i := 0; i < l1; i++ {
		if data[i] != dataExpected[i] {
			t.Fatalf("After pack, data[%d] is %x, not equal to dataExpected[%d]: %x\n", i, data[i], i, dataExpected[i])
		}
	}
}

func TestCmpp3FwdReqPktUnpack(t *testing.T) {
	data := []byte{
		0x00, 0x00, 0x01, 0x35, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x17, 0x31, 0x30, 0x30, 0x32,
		0x30, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x02, 0x31, 0x33, 0x35, 0x30, 0x30, 0x30, 0x30, 0x32, 0x36, 0x39, 0x36, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x33, 0x32, 0x31, 0x33, 0x32, 0x31,
		0x30, 0x32, 0x31, 0x30, 0x00, 0x00, 0x00, 0x00, 0x31, 0x35, 0x31, 0x31, 0x31, 0x35, 0x31, 0x33,
		0x31, 0x35, 0x35, 0x35, 0x31, 0x30, 0x31, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x39, 0x39, 0x39, 0x38, 0x38,
		0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x01, 0x31, 0x33, 0x35, 0x30, 0x30, 0x30, 0x30, 0x32, 0x36, 0x39, 0x36, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x6d, 0x4b, 0x8b, 0xd5, 0x00, 0x67, 0x00,
		0x6f, 0x00, 0x63, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x70, 0x00, 0x20, 0x00, 0x66, 0x00, 0x77, 0x00,
		0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00,
	}

	p := &cmpp.Cmpp3FwdReqPkt{}
	err := p.Unpack(data[8:])
	if err != nil {
		t.Fatal("Cmpp3FwdReqPkt unpack error:", err)
	}

	var resultSet = []struct {
		name          string
		value         interface{}
		expectedValue interface{}
	}{
		{"SeqId", p.SeqId, seqId},
		{"SourceId", p.SourceId, sourceId},
		{"DestinationId", p.DestinationId, destinationId},
		{"NodesCount", p.NodesCount, nodesCount},
		{"MsgId", p.MsgId, fwdMsgId},
		{"MsgFwdType", p.MsgFwdType, msgFwdType},
		{"MsgId", p.MsgId, fwdMsgId},
		{"PkTotal", p.PkTotal, fwdPkTotal},
		{"PkNumber", p.PkNumber, fwdPkNumber},
		{"RegisteredDelivery", p.RegisteredDelivery, fwdRegisteredDelivery},
		{"MsgLevel", p.MsgLevel, fwdMsgLevel},
		{"ServiceId", p.ServiceId, fwdServiceId},
		{"FeeUserType", p.FeeUserType, fwdFeeUserType},
		{"FeeTerminalId", p.FeeTerminalId, fwdFeeTerminalId},
		{"FeeTerminalUserType", p.FeeTerminalUserType, fwdFeeTerminalUserType},
		{"MsgFmt", p.MsgFmt, fwdMsgFmt},
		{"MsgSrc", p.MsgSrc, fwdMsgSrc},
		{"FeeType", p.FeeType, fwdFeeType},
		{"FeeCode", p.FeeCode, fwdFeeCode},
		{"ValidTime", p.ValidTime, fwdValidTime},
		{"AtTime", p.AtTime, fwdAtTime},
		{"SrcId", p.SrcId, fwdSrcId},
		{"SrcUserType", p.SrcUserType, fwdSrcUserType},
		{"SrcType", p.SrcType, fwdSrcType},
		{"DestUsrTl", p.DestUsrTl, fwdDestUsrTl},
		{"DestId", p.DestId[0], fwdDestId[0]},
		{"DestUserType", p.DestUserType, fwdDestUserType},
		{"MsgLength", p.MsgLength, fwdMsgLength},
		{"MsgContent", p.MsgContent, fwdMsgContent},
	}

	for _, r := range resultSet {
		if r.value != r.expectedValue {
			t.Fatalf("After unpack, %s in packet is %#v, not equal to the expected value: %#v\n", r.name, r.value, r.expectedValue)
		}
	}
}

func TestCmpp3FwdRspPktPack(t *testing.T) {
	p := &cmpp.Cmpp3FwdRspPkt{
		MsgId:    12878564852733378560, //0xb2, 0xb9, 0xda, 0x80, 0x00, 0x01, 0x00, 0x00
		PkTotal:  fwdPkTotal,
		PkNumber: fwdPkNumber,
		Result:   1,
	}

	data, err := p.Pack(seqId)
	if err != nil {
		t.Fatal("Cmpp3FwdRspPkt pack error:", err)
	}

	if p.SeqId != seqId {
		t.Fatalf("After pack, seqId is %d, not equal to expected: %d\n", p.SeqId, seqId)
	}

	dataExpected := []byte{
		0x00, 0x00, 0x00, 0x1a, 0x80, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x17,
		0xb2, 0xb9, 0xda, 0x80, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
		0x00, 0x01,
	}

	l1 := len(data)
	l2 := len(dataExpected)
	if l1 != l2 {
		t.Fatalf("After pack, data length is %d, not equal to length expected: %d\n", l1, l2)
	}

	for i := 0; i < l1; i++ {
		if data[i] != dataExpected[i] {
			t.Fatalf("After pack, data[%d] is %x, not equal to dataExpected[%d]: %x\n", i, data[i], i, dataExpected[i])
		}
	}
}

func TestCmpp3FwdRspPktUnpack(t *testing.T) {
	data := []byte{
		0x00, 0x00, 0x00, 0x1a, 0x80, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x17,
		0xb2, 0xb9, 0xda, 0x80, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
		0x00, 0x01,
	}

	p := &cmpp.Cmpp3FwdRspPkt{}
	err := p.Unpack(data[8:])
	if err != nil {
		t.Fatal("Cmpp3FwdRspPkt unpack error:", err)
	}

	if p.SeqId != seqId {
		t.Fatalf("After unpack, seqId in packet is %x, not equal to the expected value: %x\n", p.SeqId, seqId)
	}

	var msgId uint64 = 12878564852733378560 //0xb2, 0xb9, 0xda, 0x80, 0x00, 0x01, 0x00, 0x00
	if p.MsgId != msgId {
		t.Fatalf("After unpack, msgId in packet is %d, not equal to the expected value: %d\n", p.MsgId, msgId)
	}
	if p.PkTotal != 0x1 {
		t.Fatalf("After unpack, pktotal in packet is %d, not equal to the expected value: %d\n", p.Result, 0)
	}
	if p.PkNumber != 0x1 {
		t.Fatalf("After unpack, pktotal in packet is %d, not equal to the expected value: %d\n", p.Result, 0)
	}
	if p.Result != 0x1 {
		t.Fatalf("After unpack, result in packet is %d, not equal to the expected value: %d\n", p.Result, 0)
	}
}

func BenchmarkCmpp2FwdReqPktPack(b *testing.B) {
	p := &cmpp.Cmpp2FwdReqPkt{
		SourceId:           sourceId,
		DestinationId:      destinationId,
		NodesCount:         nodesCount,
		MsgFwdType:         msgFwdType,
		PkTotal:            fwdPkTotal,
		PkNumber:           fwdPkNumber,
		RegisteredDelivery: fwdRegisteredDelivery,
		MsgLevel:           fwdMsgLevel,
		ServiceId:          fwdServiceId,
		FeeUserType:        fwdFeeUserType,
		FeeTerminalId:      fwdFeeTerminalId,
		MsgFmt:             fwdMsgFmt,
		MsgSrc:             fwdMsgSrc,
		FeeType:            fwdFeeType,
		FeeCode:            fwdFeeCode,
		ValidTime:          fwdValidTime,
		AtTime:             fwdAtTime,
		SrcId:              fwdSrcId,
		DestUsrTl:          fwdDestUsrTl,
		DestId:             fwdDestId,
		MsgLength:          fwdMsgLength,
		MsgContent:         fwdMsgContent,
	}

	for i := 0; i < b.N; i++ {
		p.Pack(seqId)
	}
}

func BenchmarkCmpp2FwdReqPktUnpack(b *testing.B) {
	data := []byte{
		0x00, 0x00, 0x00, 0x17, 0x31, 0x30, 0x30, 0x32,
		0x30, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x02, 0x31, 0x33, 0x35, 0x30, 0x30, 0x30, 0x30, 0x32, 0x36, 0x39, 0x36, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x33, 0x32, 0x31, 0x33, 0x32, 0x31, 0x30,
		0x32, 0x31, 0x30, 0x00, 0x00, 0x00, 0x00, 0x31, 0x35, 0x31, 0x31, 0x31, 0x35, 0x31, 0x33, 0x31,
		0x35, 0x35, 0x35, 0x31, 0x30, 0x31, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x39, 0x39, 0x39, 0x38, 0x38, 0x38,
		0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x31,
		0x33, 0x35, 0x30, 0x30, 0x30, 0x30, 0x32, 0x36, 0x39, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x18, 0x6d, 0x4b, 0x8b, 0xd5, 0x00, 0x67, 0x00, 0x6f, 0x00, 0x63, 0x00,
		0x6d, 0x00, 0x70, 0x00, 0x70, 0x00, 0x20, 0x00, 0x66, 0x00, 0x77, 0x00, 0x64, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00,
	}

	p := &cmpp.Cmpp2FwdReqPkt{}

	for i := 0; i < b.N; i++ {
		p.Unpack(data)
	}
}

func BenchmarkCmpp3FwdReqPktPack(b *testing.B) {
	p := &cmpp.Cmpp3FwdReqPkt{
		SourceId:            sourceId,
		DestinationId:       destinationId,
		NodesCount:          nodesCount,
		MsgFwdType:          msgFwdType,
		MsgId:               fwdMsgId,
		PkTotal:             fwdPkTotal,
		PkNumber:            fwdPkNumber,
		RegisteredDelivery:  fwdRegisteredDelivery,
		MsgLevel:            fwdMsgLevel,
		ServiceId:           fwdServiceId,
		FeeUserType:         fwdFeeUserType,
		FeeTerminalId:       fwdFeeTerminalId,
		FeeTerminalUserType: fwdFeeTerminalUserType,
		MsgFmt:              fwdMsgFmt,
		MsgSrc:              fwdMsgSrc,
		FeeType:             fwdFeeType,
		FeeCode:             fwdFeeCode,
		ValidTime:           fwdValidTime,
		AtTime:              fwdAtTime,
		SrcId:               fwdSrcId,
		SrcUserType:         fwdSrcUserType,
		SrcType:             fwdSrcType,
		DestUsrTl:           fwdDestUsrTl,
		DestId:              fwdDestId,
		DestUserType:        fwdDestUserType,
		MsgLength:           fwdMsgLength,
		MsgContent:          fwdMsgContent,
	}

	for i := 0; i < b.N; i++ {
		p.Pack(seqId)
	}
}

func BenchmarkCmpp3FwdReqPktUnpack(b *testing.B) {
	data := []byte{
		0x00, 0x00, 0x00, 0x17, 0x31, 0x30, 0x30, 0x32,
		0x30, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x02, 0x31, 0x33, 0x35, 0x30, 0x30, 0x30, 0x30, 0x32, 0x36, 0x39, 0x36, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x33, 0x32, 0x31, 0x33, 0x32, 0x31,
		0x30, 0x32, 0x31, 0x30, 0x00, 0x00, 0x00, 0x00, 0x31, 0x35, 0x31, 0x31, 0x31, 0x35, 0x31, 0x33,
		0x31, 0x35, 0x35, 0x35, 0x31, 0x30, 0x31, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x39, 0x39, 0x39, 0x38, 0x38,
		0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x01, 0x31, 0x33, 0x35, 0x30, 0x30, 0x30, 0x30, 0x32, 0x36, 0x39, 0x36, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x6d, 0x4b, 0x8b, 0xd5, 0x00, 0x67, 0x00,
		0x6f, 0x00, 0x63, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x70, 0x00, 0x20, 0x00, 0x66, 0x00, 0x77, 0x00,
		0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00,
	}
	p := &cmpp.Cmpp3FwdReqPkt{}

	for i := 0; i < b.N; i++ {
		p.Unpack(data)
	}
}
