package icssessionmanager

import (
	"strings"

	"gitlab.com/ics_cinnamon/voicegateway/icspacketparser"
)

const (
	ICS_SIP_AUTOMATA_REGISTER = 32767
	//ICS_SIP_AUTOMATA_REGISTER = 2
	ICS_SIP_AUTOMATA_INVITE = 32767
	ICS_SIP_AUTOMATA_ACK    = 32767
	ICS_SIP_AUTOMATA_CANCEL = 14336
	ICS_SIP_AUTOMATA_BYE    = 32767
	ICS_SIP_AUTOMATA_NOTIFY = 32767
	ICS_SIP_AUTOMATA_OPTIONS = 32767
	ICS_SIP_AUTOMATA_REFER = 32767
	/*
		ICS_SIP_AUTOMATA_INVITE = 11266
		ICS_SIP_AUTOMATA_ACK    = 32767
		ICS_SIP_AUTOMATA_CANCEL = 14336
		ICS_SIP_AUTOMATA_BYE    = 32767
	*/
	//ICS_SIP_AUTOMATA_BYE    = 0
)

const (
	ICS_SIP_JOB_TYPE_REGISTER = 1 << iota
	ICS_SIP_JOB_TYPE_INVITE
	ICS_SIP_JOB_TYPE_PUBLISH
	ICS_SIP_JOB_TYPE_OPTIONS
	ICS_SIP_JOB_TYPE_INFO
	ICS_SIP_JOB_TYPE_UPDATE
	ICS_SIP_JOB_TYPE_REFER
	ICS_SIP_JOB_TYPE_SUBSCRIBE
	ICS_SIP_JOB_TYPE_MESSAGE
	ICS_SIP_JOB_TYPE_NOTIFY
	ICS_SIP_JOB_TYPE_PRACK
	ICS_SIP_JOB_TYPE_ACK
	ICS_SIP_JOB_TYPE_BYE
	ICS_SIP_JOB_TYPE_CANCEL
)

func SessionAvailableSipMethod(sip *icspacketparser.SIP) bool {
	if sip.Method == icspacketparser.ICS_SIP_METHOD_INVITE || sip.Method == icspacketparser.ICS_SIP_METHOD_CANCEL || sip.Method == icspacketparser.ICS_SIP_METHOD_BYE || sip.Method == icspacketparser.ICS_SIP_METHOD_ACK || sip.Method == icspacketparser.ICS_SIP_METHOD_NOTIFY || sip.Method == icspacketparser.ICS_SIP_METHOD_REFER {
		return true
	} else if sip.Method == icspacketparser.ICS_SIP_METHOD_SIP20 {
		if strings.Contains(sip.Cseq, " INVITE") || strings.Contains(sip.Cseq, " CANCEL") || strings.Contains(sip.Cseq, " BYE") || strings.Contains(sip.Cseq, " ACK") || strings.Contains(sip.Cseq, " REGISTER") || strings.Contains(sip.Cseq, " OPTIONS") {
			return true
			/*
				if sip.ResType == "183" || sip.ResType == "200" {
					return true
				}
			*/
		}
	}
	return false
}

func (s *IcsSession) CheckAutomataWithType(methodType int) bool {
	return (s.MethodAutomata & methodType) == methodType
}

func (s *IcsSession) CheckAutomata(sip *icspacketparser.SIP) bool {
	jobType := GetJobType(sip)

	return (s.MethodAutomata & jobType) == jobType
	/*
		// fmt.Println("^^^^^", "s.MethodAutomata,jobType,sip.Method", s.MethodAutomata, jobType, sip.Method)
		if (s.MethodAutomata&jobType) == jobType || jobType == ICS_SIP_JOB_TYPE_BYE {
			// fmt.Println("^^^^^", "automata find ok")
			return true
		}
		// fmt.Println("^^^^^", "not allow automata sip.Cseq", sip.Cseq)

		return false
	*/
}

func GetJobType(sip *icspacketparser.SIP) int {
	if sip.Method == icspacketparser.ICS_SIP_METHOD_SIP20 {
		if strings.Contains(sip.Cseq, " INVITE") {
			return ICS_SIP_JOB_TYPE_INVITE
		} else if strings.Contains(sip.Cseq, " ACK") {
			return ICS_SIP_JOB_TYPE_ACK
		} else if strings.Contains(sip.Cseq, " BYE") {
			return ICS_SIP_JOB_TYPE_BYE
		} else if strings.Contains(sip.Cseq, " REGISTER") {
			return ICS_SIP_JOB_TYPE_REGISTER
		} else if strings.Contains(sip.Cseq, " CANCEL") {
			return ICS_SIP_JOB_TYPE_CANCEL
		} else if strings.Contains(sip.Cseq, " OPTIONS") {
			return ICS_SIP_JOB_TYPE_OPTIONS
		}
	} else if sip.Method == icspacketparser.ICS_SIP_METHOD_REGISTER {
		return ICS_SIP_JOB_TYPE_REGISTER
	} else if sip.Method == icspacketparser.ICS_SIP_METHOD_INVITE {
		return ICS_SIP_JOB_TYPE_INVITE
	} else if sip.Method == icspacketparser.ICS_SIP_METHOD_CANCEL {
		return ICS_SIP_JOB_TYPE_CANCEL
	} else if sip.Method == icspacketparser.ICS_SIP_METHOD_BYE {
		return ICS_SIP_JOB_TYPE_BYE
	} else if sip.Method == icspacketparser.ICS_SIP_METHOD_ACK {
		return ICS_SIP_JOB_TYPE_ACK
	} else if sip.Method == icspacketparser.ICS_SIP_METHOD_NOTIFY {
		return ICS_SIP_JOB_TYPE_NOTIFY
	} else if sip.Method == icspacketparser.ICS_SIP_METHOD_REFER {
		return ICS_SIP_JOB_TYPE_REFER
	}
	return -1
}

func (s *IcsSession) SetSessionMethodWithType(methodType int) {
	s.MethodAutomata = methodType
}

func (s *IcsSession) SetSessionMethod(sip icspacketparser.SIP) {
	if sip.Method == icspacketparser.ICS_SIP_METHOD_SIP20 {
		if strings.Contains(sip.Cseq, " REGISTER") {
			s.MethodAutomata = ICS_SIP_AUTOMATA_REGISTER
			//fmt.Println(">>>>>>>>>>", s.MethodAutomata, ICS_SIP_AUTOMATA_REGISTER)
		} else if strings.Contains(sip.Cseq, " INVITE") {
			s.MethodAutomata = ICS_SIP_AUTOMATA_INVITE
		} else if strings.Contains(sip.Cseq, " CANCEL") {
			s.MethodAutomata = ICS_SIP_AUTOMATA_CANCEL
		} else if strings.Contains(sip.Cseq, " BYE") {
			s.MethodAutomata = ICS_SIP_AUTOMATA_BYE
		} else if strings.Contains(sip.Cseq, " ACK") {
			s.MethodAutomata = ICS_SIP_AUTOMATA_ACK
		} else if strings.Contains(sip.Cseq, " OPTIONS") {
			s.MethodAutomata = ICS_SIP_AUTOMATA_OPTIONS
		} else if strings.Contains(sip.Cseq, " REFER") {
			s.MethodAutomata = ICS_SIP_AUTOMATA_REFER
		}
	} else if sip.Method == icspacketparser.ICS_SIP_METHOD_REGISTER {
		s.MethodAutomata = ICS_SIP_AUTOMATA_REGISTER
	} else if sip.Method == icspacketparser.ICS_SIP_METHOD_INVITE {
		s.MethodAutomata = ICS_SIP_AUTOMATA_INVITE
	} else if sip.Method == icspacketparser.ICS_SIP_METHOD_CANCEL {
		s.MethodAutomata = ICS_SIP_AUTOMATA_CANCEL
	} else if sip.Method == icspacketparser.ICS_SIP_METHOD_BYE {
		s.MethodAutomata = ICS_SIP_AUTOMATA_BYE
	} else if sip.Method == icspacketparser.ICS_SIP_METHOD_ACK {
		s.MethodAutomata = ICS_SIP_AUTOMATA_ACK
	} else if sip.Method == icspacketparser.ICS_SIP_METHOD_NOTIFY {
		s.MethodAutomata = ICS_SIP_AUTOMATA_NOTIFY
	} else if sip.Method == icspacketparser.ICS_SIP_METHOD_REFER {
		s.MethodAutomata = ICS_SIP_AUTOMATA_REFER
	}
}
