// 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 (
	"testing"

	"github.com/bigwhite/gocmpp"
)

func TestCmpp3DeliverReqPktPack(t *testing.T) {
	p := &cmpp.Cmpp3DeliverReqPkt{
		MsgId:            13025908756704198656,
		DestId:           "900001",
		MsgFmt:           0,
		SrcTerminalId:    "13412340000",
		SrcTerminalType:  0,
		RegisterDelivery: 0,
		MsgLength:        18,
		MsgContent:       "This is a test MO.",
	}

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

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

	dataExpected := []byte{
		0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x05,
		0x00, 0x00, 0x00, 0x01, 0xb4, 0xc5, 0x53, 0x00, 0x00, 0x01, 0x00, 0x00, 0x39, 0x30, 0x30, 0x30,
		0x30, 0x31, 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, 0x31, 0x33,
		0x34, 0x31, 0x32, 0x33, 0x34, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x12, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20,
		0x4d, 0x4f, 0x2e, 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 TestCmpp3DeliverReqPktUnpack(t *testing.T) {
	data := []byte{
		0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x05,
		0x00, 0x00, 0x00, 0x01, 0xb4, 0xc5, 0x53, 0x00, 0x00, 0x01, 0x00, 0x00, 0x39, 0x30, 0x30, 0x30,
		0x30, 0x31, 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, 0x31, 0x33,
		0x34, 0x31, 0x32, 0x33, 0x34, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x12, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20,
		0x4d, 0x4f, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	}

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

	var resultSet = []struct {
		name          string
		value         interface{}
		expectedValue interface{}
	}{
		{"SeqId", p.SeqId, uint32(0x1)},
		{"MsgId", p.MsgId, uint64(13025908756704198656)},
		{"DestId", p.DestId, "900001"},
		{"ServiceId", p.ServiceId, ""},
		{"TpPid", p.TpPid, uint8(0)},
		{"TpUdhi", p.TpUdhi, uint8(0)},
		{"MsgFmt", p.MsgFmt, uint8(0)},
		{"SrcTerminalId", p.SrcTerminalId, "13412340000"},
		{"SrcTerminalType", p.SrcTerminalType, uint8(0)},
		{"RegisterDelivery", p.RegisterDelivery, uint8(0)},
		{"MsgLength", p.MsgLength, uint8(18)},
		{"MsgContent", p.MsgContent, "This is a test MO."},
		{"LinkId", p.LinkId, ""},
	}

	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 TestCmpp3DeliverRspPktPack(t *testing.T) {
	p := &cmpp.Cmpp3DeliverRspPkt{
		MsgId:  13025908756704198656,
		Result: 0,
	}

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

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

	dataExpected := []byte{
		0x00, 0x00, 0x00, 0x18, 0x80, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0xb4, 0xc5, 0x53, 0x00,
		0x00, 0x01, 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 TestCmpp3DeliverRspPktUnpack(t *testing.T) {
	data := []byte{
		0x00, 0x00, 0x00, 0x18, 0x80, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0xb4, 0xc5, 0x53, 0x00,
		0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	}

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

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

	var msgId uint64 = 13025908756704198656
	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.Result != 0x0 {
		t.Fatalf("After unpack, result in packet is %d, not equal to the expected value: %d\n", p.Result, 0)
	}
}

func TestCmpp2DeliverReqPktPack(t *testing.T) {
	p := &cmpp.Cmpp2DeliverReqPkt{
		MsgId:            13052947396898652160,
		DestId:           "900001",
		MsgFmt:           0,
		SrcTerminalId:    "13412340000",
		RegisterDelivery: 0,
		MsgLength:        18,
		MsgContent:       "This is a test MO.",
	}

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

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

	dataExpected := []byte{
		0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x05,
		0x00, 0x00, 0x00, 0x05, 0xb5, 0x25, 0x62, 0x80, 0x00, 0x01, 0x00, 0x00, 0x39, 0x30, 0x30, 0x30,
		0x30, 0x31, 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, 0x31, 0x33,
		0x34, 0x31, 0x32, 0x33, 0x34, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x12, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74,
		0x65, 0x73, 0x74, 0x20, 0x4d, 0x4f, 0x2e, 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 TestCmpp2DeliverReqPktUnpack(t *testing.T) {
	data := []byte{
		0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x05,
		0x00, 0x00, 0x00, 0x05, 0xb5, 0x25, 0x62, 0x80, 0x00, 0x01, 0x00, 0x00, 0x39, 0x30, 0x30, 0x30,
		0x30, 0x31, 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, 0x31, 0x33,
		0x34, 0x31, 0x32, 0x33, 0x34, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x12, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74,
		0x65, 0x73, 0x74, 0x20, 0x4d, 0x4f, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	}

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

	var resultSet = []struct {
		name          string
		value         interface{}
		expectedValue interface{}
	}{
		{"SeqId", p.SeqId, uint32(0x5)},
		{"MsgId", p.MsgId, uint64(13052947396898652160)},
		{"DestId", p.DestId, "900001"},
		{"ServiceId", p.ServiceId, ""},
		{"TpPid", p.TpPid, uint8(0)},
		{"TpUdhi", p.TpUdhi, uint8(0)},
		{"MsgFmt", p.MsgFmt, uint8(0)},
		{"SrcTerminalId", p.SrcTerminalId, "13412340000"},
		{"RegisterDelivery", p.RegisterDelivery, uint8(0)},
		{"MsgLength", p.MsgLength, uint8(18)},
		{"MsgContent", p.MsgContent, "This is a test MO."},
	}

	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 TestCmpp2DeliverRspPktPack(t *testing.T) {
	p := &cmpp.Cmpp2DeliverRspPkt{
		MsgId:  13052947396898652160,
		Result: 0,
	}

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

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

	dataExpected := []byte{
		0x00, 0x00, 0x00, 0x15, 0x80, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0xb5, 0x25, 0x62, 0x80,
		0x00, 0x01, 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 TestCmpp2DeliverRspPktUnpack(t *testing.T) {
	data := []byte{
		0x00, 0x00, 0x00, 0x15, 0x80, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0xb5, 0x25, 0x62, 0x80,
		0x00, 0x01, 0x00, 0x00, 0x00,
	}

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

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

	var msgId uint64 = 13052947396898652160
	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.Result != 0x0 {
		t.Fatalf("After unpack, result in packet is %d, not equal to the expected value: %d\n", p.Result, 0)
	}
}

func BenchmarkCmpp2DeliverReqPktPack(b *testing.B) {
	p := &cmpp.Cmpp2DeliverReqPkt{
		MsgId:            13052947396898652160,
		DestId:           "900001",
		MsgFmt:           0,
		SrcTerminalId:    "13412340000",
		RegisterDelivery: 0,
		MsgLength:        18,
		MsgContent:       "This is a test MO.",
	}

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

func BenchmarkCmpp2DeliverReqPktUnpack(b *testing.B) {
	data := []byte{
		0x00, 0x00, 0x00, 0x05, 0xb5, 0x25, 0x62, 0x80, 0x00, 0x01, 0x00, 0x00, 0x39, 0x30, 0x30, 0x30,
		0x30, 0x31, 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, 0x31, 0x33,
		0x34, 0x31, 0x32, 0x33, 0x34, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x12, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74,
		0x65, 0x73, 0x74, 0x20, 0x4d, 0x4f, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	}

	p := &cmpp.Cmpp2DeliverReqPkt{}

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

func BenchmarkCmpp3DeliverReqPktPack(b *testing.B) {
	p := &cmpp.Cmpp3DeliverReqPkt{
		MsgId:            13025908756704198656,
		DestId:           "900001",
		MsgFmt:           0,
		SrcTerminalId:    "13412340000",
		SrcTerminalType:  0,
		RegisterDelivery: 0,
		MsgLength:        18,
		MsgContent:       "This is a test MO.",
	}

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

func BenchmarkCmpp3DeliverReqPktUnpack(b *testing.B) {
	data := []byte{
		0x00, 0x00, 0x00, 0x01, 0xb4, 0xc5, 0x53, 0x00, 0x00, 0x01, 0x00, 0x00, 0x39, 0x30, 0x30, 0x30,
		0x30, 0x31, 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, 0x31, 0x33,
		0x34, 0x31, 0x32, 0x33, 0x34, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x12, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20,
		0x4d, 0x4f, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	}

	p := &cmpp.Cmpp2DeliverReqPkt{}

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