package matcher

import (
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/activedirectory"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/cassandra"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/dns"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/ftp"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/http"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/imap"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/ldap"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/mongodb"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/mssql"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/mysql"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/netbios"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/oracle"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/packet"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/pop"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/redis"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/rmi"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/smb"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/smtp"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/snmp"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/ssh"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/telnet"
	"git.loafle.net/overflow/overflow_probe/discovery/core/scan/service/matcher/wmi"
	"git.loafle.net/overflow/overflow_probe/discovery/discovery/types"
)

var (
	TcpMatchers []Matcher
	UdpMatchers []UDPMatcher
)

func init() {
	//TCP
	TcpMatchers = append(TcpMatchers, smtp.NewSmtpMatcher())
	TcpMatchers = append(TcpMatchers, ldap.NewLDAPMatcher())
	TcpMatchers = append(TcpMatchers, activedirectory.NewActiveDirectoryMatcher())
	TcpMatchers = append(TcpMatchers, mongodb.NewMongoDBMatcher())
	TcpMatchers = append(TcpMatchers, mysql.NewMySqlMatcher())
	TcpMatchers = append(TcpMatchers, mssql.NewMSSqlMatcher())
	TcpMatchers = append(TcpMatchers, redis.NewRedisMatcher())
	TcpMatchers = append(TcpMatchers, redis.NewRedisProtectedMatcher())
	TcpMatchers = append(TcpMatchers, netbios.NewNetBiosMatcher())
	TcpMatchers = append(TcpMatchers, smb.NewSMBMatcher())
	TcpMatchers = append(TcpMatchers, cassandra.NewCassandraMatcher())
	TcpMatchers = append(TcpMatchers, imap.NewIMAPMatcher())
	TcpMatchers = append(TcpMatchers, oracle.NewOracleMatcher())
	TcpMatchers = append(TcpMatchers, pop.NewPOPMatcher())
	TcpMatchers = append(TcpMatchers, wmi.NewWMIMatcher())
	TcpMatchers = append(TcpMatchers, ftp.NewFTPMatcher())
	TcpMatchers = append(TcpMatchers, http.NewHTTPMatcher())
	TcpMatchers = append(TcpMatchers, rmi.NewRMIMatcher())
	TcpMatchers = append(TcpMatchers, ssh.NewSSHMatcher())
	TcpMatchers = append(TcpMatchers, telnet.NewTelnetMatcher())
	UdpMatchers = append(UdpMatchers, dns.NewDnsMatcher())
	UdpMatchers = append(UdpMatchers, snmp.NewSNMPv2Matcher())
	UdpMatchers = append(UdpMatchers, snmp.NewSNMPv3Matcher())
}

type Matcher interface {
	Match(index int, packet *packet.Packet, info *types.ServiceScanInfo) bool

	PacketCount() int
	Packet(index int) *packet.Packet
	ServiceName() string

	IsError(index int, packet *packet.Packet, info *types.ServiceScanInfo) bool
	IsNoResponse(index int) bool
	IsPrePacket() bool
}

type UDPMatcher interface {
	Matcher
	IsSend(port int) bool
}

func GetTcpMatchers(ispre bool) []Matcher {

	retMatchers := make([]Matcher, 0)
	l := len(TcpMatchers)
	for i := 0; i < l; i++ {
		c := TcpMatchers[i].IsPrePacket()
		if c == ispre {
			retMatchers = append(retMatchers, TcpMatchers[i])
		}
	}

	return retMatchers
}

func GetUdpMatchers() []UDPMatcher {

	retMatchers := make([]UDPMatcher, 0)
	l := len(UdpMatchers)
	for i := 0; i < l; i++ {
		retMatchers = append(retMatchers, UdpMatchers[i])
	}

	return retMatchers
}

func GetMatcherByName(serName string) Matcher {
	for _, m := range TcpMatchers {
		if m.ServiceName() == serName {
			return m
		}
	}
	for _, m := range UdpMatchers {
		if m.ServiceName() == serName {
			return m
		}
	}
	return nil
}
