package main

import (
	"bytes"
	"encoding/binary"
	"log"
	"net"
	"sync"

	"smpptester/pdu"
)

func init() {
	log.SetFlags(log.Lmicroseconds | log.Lshortfile)
}

// Function to create a submit_sm PDU
func createSubmitSMPDU() []byte {
	// Example values for the submit_sm PDU fields
	serviceType := "CMT"
	sourceAddrTON := byte(0x01)
	sourceAddrNPI := byte(0x01)
	sourceAddr := "12345"
	destAddrTON := byte(0x01)
	destAddrNPI := byte(0x01)
	destinationAddr := "67890"
	esmClass := byte(0x00)
	protocolID := byte(0x00)
	priorityFlag := byte(0x00)
	scheduleDeliveryTime := ""
	validityPeriod := ""
	registeredDelivery := byte(0x01)
	replaceIfPresentFlag := byte(0x00)
	dataCoding := byte(0x01)
	smDefaultMsgID := byte(0x00)
	shortMessage := "Hello, SMPP!"

	// Calculate the length of the PDU
	headerLength := 16
	bodyLength := 1 + len(serviceType) + 1 + 1 + len(sourceAddr) + 1 + 1 + len(destinationAddr) + 1 + 1 + len(scheduleDeliveryTime) + 1 + len(validityPeriod) + 1 + 1 + 1 + 1 + 1 + len(shortMessage)
	totalLength := headerLength + bodyLength

	// Create a buffer to hold the PDU
	var buffer bytes.Buffer

	// Command Length
	binary.Write(&buffer, binary.BigEndian, uint32(totalLength))

	// Command ID (submit_sm)
	binary.Write(&buffer, binary.BigEndian, uint32(0x00000004))

	// Command Status (0x00000000 for ESME_ROK)
	binary.Write(&buffer, binary.BigEndian, uint32(0x00000000))

	// Sequence Number (example value)
	binary.Write(&buffer, binary.BigEndian, uint32(0x00000001))

	// Service Type
	buffer.WriteString(serviceType)
	buffer.WriteByte(0x00)

	// Source Address TON
	buffer.WriteByte(sourceAddrTON)

	// Source Address NPI
	buffer.WriteByte(sourceAddrNPI)

	// Source Address
	buffer.WriteString(sourceAddr)
	buffer.WriteByte(0x00)

	// Destination Address TON
	buffer.WriteByte(destAddrTON)

	// Destination Address NPI
	buffer.WriteByte(destAddrNPI)

	// Destination Address
	buffer.WriteString(destinationAddr)
	buffer.WriteByte(0x00)

	// ESM Class
	buffer.WriteByte(esmClass)

	// Protocol ID
	buffer.WriteByte(protocolID)

	// Priority Flag
	buffer.WriteByte(priorityFlag)

	// Schedule Delivery Time
	buffer.WriteString(scheduleDeliveryTime)
	buffer.WriteByte(0x00)

	// Validity Period
	buffer.WriteString(validityPeriod)
	buffer.WriteByte(0x00)

	// Registered Delivery
	buffer.WriteByte(registeredDelivery)

	// Replace If Present Flag
	buffer.WriteByte(replaceIfPresentFlag)

	// Data Coding
	buffer.WriteByte(dataCoding)

	// SM Default Message ID
	buffer.WriteByte(smDefaultMsgID)

	// Short Message Length
	buffer.WriteByte(byte(len(shortMessage)))

	// Short Message
	buffer.WriteString(shortMessage)

	// Return the PDU as a byte slice
	return buffer.Bytes()
}

func main() {
	// addr := ":2775"
	// listener, err := net.Listen("tcp", addr)
	// if err != nil {
	// 	log.Fatalf("Failed to start SMPP server: %v", err)
	// }
	// defer listener.Close()
	// log.Printf("SMPP server started on %s", addr)

	// go func() {
	// 	for {
	// 		conn, err := listener.Accept()
	// 		if err != nil {
	// 			log.Printf("Failed to accept connection: %v", err)
	// 			continue
	// 		}
	// 		go handleConnection(conn)
	// 	}
	// }()
	submit := &pdu.SUBMIT_SM{
		Header: &pdu.PDU_HEADER{
			Command_length:  0,
			Command_id:      4,
			Command_status:  0,
			Sequence_number: 1,
		},
		Service_type:           "hehe",
		Source_addr_ton:        0x01,
		Source_addr_npi:        0x01,
		Source_addr:            "12345",
		Dest_addr_ton:          0x01,
		Dest_addr_npi:          0x01,
		Destination_addr:       "67890",
		Esm_class:              0x00,
		Protocol_id:            0x00,
		Priority_flag:          0x00,
		Schedule_delivery_time: "",
		Validity_period:        "",
		Registered_delivery:    0x01,
		Replace_if_present:     0x00,
		Data_coding:            0x01,
		Sm_default_msg_id:      0x00,
		Short_message:          "Hello, SMPP!",
	}
	submit.UpdateSize()
	buf := pdu.ByteBufferPool.Get(submit.Size())
	defer pdu.ByteBufferPool.Put(buf)
	submit.Encode(buf)
	log.Println(buf.Bytes())
	log.Println(createSubmitSMPDU())
	// log.Println(pdu.Encode())
	// serviceType := "CMT"
	// sourceAddrTON := byte(0x01)
	// sourceAddrNPI := byte(0x01)
	// sourceAddr := "12345"
	// destAddrTON := byte(0x01)
	// destAddrNPI := byte(0x01)
	// destinationAddr := "67890"
	// esmClass := byte(0x00)
	// protocolID := byte(0x00)
	// priorityFlag := byte(0x00)
	// scheduleDeliveryTime := ""
	// validityPeriod := ""
	// registeredDelivery := byte(0x01)
	// replaceIfPresentFlag := byte(0x00)
	// dataCoding := byte(0x01)
	// smDefaultMsgID := byte(0x00)
	// shortMessage := "Hello, SMPP!"

	wg := &sync.WaitGroup{}
	wg.Add(1)

	conn, err := net.Dial("tcp", "localhost:2775")
	if err != nil {
		log.Printf("Failed to connect to SMPP server: %+v", err)
		return
	}
	log.Printf("Connected to SMPP server")
	defer conn.Close()

	go func() {
		conn.Write(buf.Bytes())
		data, err := conn.Read(make([]byte, 1024))
		if err != nil {
			log.Printf("Failed to read from connection: %+v", err)
			return
		}
		log.Printf("Received data: %#v", data)
	}()

	wg.Wait()
}
