package l7

import "fmt"

const (
	dmMsgHeaderSize     = 64
	dmMsgOffsetPackType = 4
	dmMsgOffsetBodyLen  = 6
	dmMsgPackTypeQuery  = 0x05
)

type DmParser struct {
	//preparedStatements map[string]string
}

func NewDmParser() *DmParser {
	//return &DmParser{preparedStatements: map[string]string{}}
	return &DmParser{}
}

func (p *DmParser) Parse(payload []byte, statementId uint32) string {

	payloadSize := uint32(len(payload))
	fmt.Println("-------dm payloadSize", payloadSize)

	if payloadSize <= dmMsgHeaderSize {
		return ""
	}

	//msgHeader := payload[:dmMsgHeaderSize]

	packType := p.getUint32By2ByteFromPayload(payload, dmMsgOffsetPackType)
	if packType != dmMsgPackTypeQuery {
		fmt.Println("-------dm packType != dmMsgPackTypeQuery ", packType)
		return ""
	}

	bodySize := p.getUint32By4ByteFromPayload(payload, dmMsgOffsetBodyLen)
	if dmMsgHeaderSize+bodySize < payloadSize {
		return ""
	}
	queryTail := ""
	if dmMsgHeaderSize+bodySize > payloadSize {
		//partial
		queryTail = "..."
	}
	payload = payload[:len(payload)-1]
	query := string(payload[dmMsgHeaderSize:]) + queryTail
	fmt.Printf("-------dm query is [%s] \n", query)
	return query
}

func (p *DmParser) getUint32By2ByteFromPayload(payload []byte, offset int) uint32 {
	var result uint32
	result = uint32(payload[offset] & 0xff)
	offset++
	result |= uint32(payload[offset]&0xff) << 8
	offset++
	return result
}

func (p *DmParser) getUint32By4ByteFromPayload(payload []byte, offset int) uint32 {
	var result uint32
	result = uint32(payload[offset] & 0xff)
	offset++
	result |= uint32(payload[offset]&0xff) << 8
	offset++
	result |= uint32(payload[offset]&0xff) << 16
	offset++
	result |= uint32(payload[offset]&0xff) << 24
	return result
}
