package types

import (
	"git.loafle.net/overflow/overflow_probe/discovery/discovery/types/timestamp"
	"git.loafle.net/overflow/overflow_probe/discovery/util/converter"
	"net"
	"sync"
)

type DiscoveryHost struct {
	M                 *sync.RWMutex             `json:"-"`
	Ip_               string                    `json:"-"`
	Ports_            map[string]*DiscoveryPort `json:"-"`
	HostName          string                    `json:"-"`
	PortDiscoveryTime timestamp.Timestamp       `json:"-"`
	Zone              *DiscoveryZone            `json:"-"`
	Histories         []*PortScanHistory        `json:"-"`

	FirstScanRange uint16 `json:"firstScanRange"`
	LastScanRange  uint16 `json:"lastScanRange"`
	Name           string `json:"name"`

	ID         int                 `json:"id,omitempty"`
	Ip         int64               `json:"ip"`
	Mac        int64               `json:"mac"`
	Ports      []*DiscoveryPort    `json:"ports"`
	CreateDate timestamp.Timestamp `json:"createDate,omitempty"`
	UpdateDate timestamp.Timestamp `json:"updateDate,omitempty"`

	Os     string `json:"os,omitempty"`
	Target bool   `json:"target,omitempty"`
}

func (h *DiscoveryHost) SetPort(key string, value *DiscoveryPort) {
	h.M.Lock()
	defer h.M.Unlock()
	h.Ports_[key] = value
}

func (h *DiscoveryHost) GetPort(key string) *DiscoveryPort {
	h.M.RLock()
	defer h.M.RUnlock()
	return h.Ports_[key]
}

type HostScanHistory struct {
	ID          int                 `json:"id,omitempty"`
	Ip          int64               `json:"ip"`
	CreateDate  timestamp.Timestamp `json:"createDate,omitempty"`
	SendDate    timestamp.Timestamp `json:"sendDate"`
	ResultDate  timestamp.Timestamp `json:"resultDate"`
	ResultType  string              `json:"resultType"`
	Description string              `json:"description"`
	Zone        *DiscoveryZone      `json:"-"`
}

type HostMgr struct {
	DiscoveryMgr
	ToPort chan *DiscoveryHost
}

func NewHost(ip net.IP, macAddr net.HardwareAddr) *DiscoveryHost {
	host := &DiscoveryHost{
		M:          new(sync.RWMutex),
		Ip_:        ip.String(),
		Ports_:     make(map[string]*DiscoveryPort, 100),
		Ip:         converter.IP4toInt(ip),
		Mac:        converter.MacToInt(macAddr),
		CreateDate: timestamp.Now(),
		UpdateDate: timestamp.Now(),
	}
	return host
}

func NewHostHistory(ip net.IP, resultType string, des string) *HostScanHistory {
	hh := &HostScanHistory{
		Ip:          converter.IP4toInt(ip),
		SendDate:    timestamp.Now(),
		ResultType:  resultType,
		Description: des,
	}

	return hh
}
func (p *DiscoveryHost) AddHistory(h *PortScanHistory) {
	p.Histories = append(p.Histories, h)
}

type PortRange struct {
	Types  string
	First  int
	Second int
}
