package login

import (
	"encoding/binary"
	"fmt"
	"primesys_producer/src/logger"
	"primesys_producer/src/protocol/crc"
	"primesys_producer/src/server/frame"
	"primesys_producer/src/types"
	"primesys_producer/src/utils"
	"strconv"
)

type LoginPacket struct {
	Imei         int64
	SerialNumber uint16
}

// Decoding of Login Packet
func DecodeLogin(f frame.Frame) (LoginPacket, error) {
	body := f.Body()

	if len(body) < 10 {
		logger.Error("Len of Login packet is not enough %d", len(body))
		return LoginPacket{}, fmt.Errorf("login packet too short: %d bytes", len(body))
	}

	imeiBin := body[1:9]
	imei, err := strconv.ParseInt(utils.ByteToString(imeiBin), 10, 64)
	if err != nil {
		return LoginPacket{}, fmt.Errorf("Imei parsing error %v", err)
	}

	serial := binary.BigEndian.Uint16(f.SerialNumber())

	return LoginPacket{
		Imei:         imei,
		SerialNumber: serial,
	}, nil
}

// Bulding ACK packet
func EncodeLoginAck(serial uint16, protocolNumber types.ProtocolNumber) []byte {
	logger.Info("Protocol Number %02X", protocolNumber)
	const requiredPacketLen = 5
	s1 := byte(serial >> 8)
	s2 := byte(serial)
	crcInput := []byte{requiredPacketLen, byte(protocolNumber), s1, s2}
	hi, lo := crc.CRC16X25Bytes(crcInput)
	ack := make([]byte, 0, 10)
	ack = append(ack, types.StartShortByte, types.StartShortByte, requiredPacketLen, byte(protocolNumber), s1, s2, hi, lo, types.StopByte1, types.StopByte2)
	return ack
}
