package service

import (
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/packet"
	"git.loafle.net/overflow/overflow_probe/discovery/discovery/types"
	"net"
)

func processPrePacket(conn net.Conn, prepacket *packet.Packet, mats []matcher.Matcher, info *types.ServiceScanInfo, m ConnFactory) bool {

	defer conn.Close()

	isFound := false
	var ser *types.DiscoveryService = nil
	for i := 0; i < len(mats); i++ {

		info.History = make([]*types.ServiceScanHistory, 0)

		AddServiceScanHistory(
			&info.History,
			types.NewServiceScanHistory(info.Port, mats[i].ServiceName(), types.DIRECTION_RECV, prepacket.Buffer))

		if mats[i].Match(0, prepacket, info) == true {
			packetCount := mats[i].PacketCount()
			if packetCount == 0 {
				ser = types.NewService(m.Type(), mats[i].ServiceName(), info.Port)
				break
			}
			isFound = false

			for j := 0; j < packetCount; j++ {

				p := mats[i].Packet(j)
				l, err := conn.Write(p.Buffer)
				if err != nil {
					break
				}
				if l != p.Len {
					break
				}
				AddServiceScanHistory(
					&info.History,
					types.NewServiceScanHistory(info.Port, mats[i].ServiceName(), types.DIRECTION_SEND, p.Buffer))

				buffer := make([]byte, 1024)
				l, err = conn.Read(buffer)
				if err != nil {
					break
				}

				AddServiceScanHistory(
					&info.History,
					types.NewServiceScanHistory(info.Port, mats[i].ServiceName(), types.DIRECTION_RECV, buffer))

				if mats[i].Match(j+1, packet.NewPacket(buffer, l), info) == true {
					isFound = true
				} else {
					isFound = false
					break
				}
			}
			if isFound == true {
				ser = types.NewService(m.Type(), mats[i].ServiceName(), info.Port)
				break
			}
		}
	}

	AddService(ser, info)
	if ser == nil {
		return false
	} else {
		return true
	}
}
