package action

import (
	"fmt"
	"os"
	"path/filepath"
	"pbx-api-gin/internal/app/stc/active"
	"pbx-api-gin/internal/app/stc/priority"
	alstatus "pbx-api-gin/internal/app/stc/sendstatus"
	"pbx-api-gin/internal/pkg/configs"
	"pbx-api-gin/pkg/lfshook"
	"pbx-api-gin/pkg/utils"
	"sort"
	"strings"
	"time"

	"github.com/sirupsen/logrus"
	"github.com/tqcenglish/amigo-go"
	"github.com/tqcenglish/amigo-go/pkg"
)

var AminInstance *amigo.Amigo
var trainInfo = ""

func HandleAMI(event map[string]string) {

	switch event["Event"] {

	case "DTMFBegin": //ICP interrupt PAD
		lfshook.NewLogger().Infof("=========%s====caller:%s=====digit:%s==", event["Event"], event["CallerIDNum"], event["Digit"])

		if utils.IsICP(event["CallerIDNum"]) && event["Exten"] != "" {

			//PA interrupt PAD
			switch event["Digit"] {
			case "#":
				//lfshook.NewLogger().Infof("===PA interrupt PAD====== ")

				InterruptRunningTask("PA")
				time.Sleep(time.Millisecond * 200) //wait endpoimt release
			case "*": //Cab cab interrupt PAD
				lfshook.NewLogger().Infof("===Cab cab interrupt PAD and====== ")

				InterruptRunningTask("C2C")
				//Hangup("2311")
				//Hangup("2381")
				time.Sleep(time.Millisecond * 100) //wait endpoimt release
			}
		}

	case "UserEvent": // RCD filename; PA;CPA; CabCab
		lfshook.NewLogger().Infof("========event:%s   File:%s", event["Event"], event["FILENAME"])

		if event["UserEvent"] == "CONTINUE" && event["Type"] != "" {
			alstatus.PaStatus("", event["Type"], "continue")
			return
		}

		if event["UserEvent"] == "CallType" && (event["Type"] == "PA" || event["Type"] == "CPA") { //PA start; check manual PA priority
			//PA & CPA interrupt others
			if utils.IsICP(event["CallerIDNum"]) { //PA

				if active.ActivedCab == "" { //No active Signal on both side,Hangup caller
					Hangup(event["CallerIDNum"])
				}

				if priority.CheckPriority("ManuPa") {
					//hangup others if priority is higher
					lfshook.NewLogger().Infof("UserEvent event :PA start")
					InterruptRunningTask("PA")         //PA interrupt other
					time.Sleep(time.Millisecond * 100) //wait endpoimt release
				} else {
					Hangup(event["CallerIDNum"]) //lowwer priority ,hangup caller
				}

			} else if utils.IsIO(event["CallerIDNum"]) { // CPA
				if priority.CheckPriority("CPA") {

					lfshook.NewLogger().Infof("========event:%s  ========devide:%d", event["Event"], active.TrainDevide)
					if active.TrainDevide == 1 || active.RadioFault == 1 { // 列车没有断开的情况下限制如下；列车断开之后CPA无任何限制
						lfshook.NewLogger().Infof("===active.TrainDevide == 1 || active.RadioFault == 1====")
					} else {
						if active.ActivedCab == "" { //No active Signal on both side,Hangup caller
							Hangup(event["CallerIDNum"])
						} else if active.ActivedCab == "1" && event["CallerIDNum"] == "1411" {
							Hangup(event["CallerIDNum"])
						} else if active.ActivedCab == "8" && event["CallerIDNum"] == "1481" {
							Hangup(event["CallerIDNum"])
						}
					}

					//hangup others if priority is higher
					InterruptRunningTask("CPA")        //CPA interrupt other
					time.Sleep(time.Millisecond * 100) //wait endpoimt release
				} else {
					Hangup(event["CallerIDNum"]) //lowwer priority ,hangup caller
				}
			}
		} else if event["UserEvent"] == "CallType" && event["Type"] == "C2C" { //CabCab start; check cab cab priority

			if priority.CheckPriority("CabCab") { // interrupt OCC-PAD
				//C2C start PAD interrupt

				taskName, _, ok := priority.RegistryTask.HighestPriorityRunningTask1()

				lfshook.NewLogger().Infof("HighestPriorityRunningTask get task :%+v", taskName)
				if ok {
					if taskName == "PAD-ICP" || taskName == "PAD-TMS" || taskName == "PA" {
						InterruptRunningTask("C2C")
						time.Sleep(time.Millisecond * 100) //wait endpoimt release
					} else {
						lfshook.NewLogger().Infof("CabCab  hangup other the one caller %s", event["CallerIDNum"])
						if event["CallerIDNum"] == "2311" {
							Hangup("2381")
						} else {
							Hangup("2311")
						}
					}
				}

			} else { // hangup caller; C2C start failed
				lfshook.NewLogger().Infof("CabCab  hangup caller %s", event["CallerIDNum"])
				Hangup(event["CallerIDNum"])
			}
			break

			//Get  record file name ,encode and upload
		} else if event["UserEvent"] == "SetRecordFile" {

			if configs.ConfigGlobal.ProcessRecord != "yes" {
				break
			}

			//检测录音文件是否存在;最多检测5次，每次间隔1秒
			var fileExists bool
			for i := 0; i < 5; i++ {
				time.Sleep(time.Second) // 等待1秒

				if _, err := os.Stat(event["FILENAME"]); err == nil {
					fileExists = true
					//lfshook.NewLogger().Infof("File found: %s", event["FILENAME"])
					break
				} else if os.IsNotExist(err) {
					//lfshook.NewLogger().Infof("File not found (attempt %d): %s", i+1, event["FILENAME"])
				} else {
					//lfshook.NewLogger().Infof("Error checking file: %v", err)
				}
			}

			if !fileExists { //5秒内没有生成录音文件
				lfshook.NewLogger().Infof("File %s not found after 5 attempts", event["FILENAME"])
				break
			}

			//获取录音文件时长，检测录音文件是否超过3min;
			duration, err := utils.GetDuration(event["FILENAME"])
			if err != nil {
				utils.Logger.Printf("%s Get duration err: %+v", event["FILENAME"], err)
				break
			}
			//lfshook.NewLogger().Infof("==========duration===== %d", duration)
			//转wav文件的采样率到22kHz，并切割位180秒每段
			var FileNames []string
			if duration >= 2000 { //超过2000秒的超长文件，不处理
				lfshook.NewLogger().Infof("Audio file time length over 2000 seconds, Ignored !")
				break
			} else if duration < 2000 { //小于2000秒文件进行转换和切割
				FileNames, err = utils.ConvertAndSegmentWAV(event["FILENAME"], strings.Replace(event["FILENAME"], ".wav", "", -1))
				if err != nil {
					lfshook.NewLogger().Infof("%s  Get duration err: %+v", event["FILENAME"], err)
					break
				}
				//lfshook.NewLogger().Infof("=============== File %+v found after convert", FileNames)
			}

			//执行加密操作,并将录音信息写入日志文件
			DstFile := ""
			if len(FileNames) > 0 { // 文件切割之后进入循环处理
				for _, filepathFull := range FileNames {

					file := strings.Replace(filepathFull, ".wav", "", -1)
					DstFile = fmt.Sprintf("%s-encrypted.wav", file)

					//lfshook.NewLogger().Infof("Bin file====%s", DstFile)
					err = utils.AudioFileEncode(DstFile, filepathFull)
					if err != nil {
						lfshook.NewLogger().Infof("Encode file: %s err: %+v", DstFile, err)
						continue
					}
					//切割&加密之后发送生成的文件名到STC;
					alstatus.SendRecordFile(DstFile, event["RecordType"])

					trainInfo = fmt.Sprintf("TrainNumber %s  ", active.TrainNum)

					if strings.Contains(event["FILENAME"], "PAD") {
						_, caller, callee := utils.GetPadInfo(event["FILENAME"])

						carNum := int(caller[2] - '0')
						//carNum := 4
						//trainInfo = fmt.Sprintf("TrainNumber %s  CarNumber %s ", active.TrainNum, active.TrainInfoMap[active.TrainNum][int(caller[2])])
						//lfshook.NewLogger().Infof("Train info carNum===caller[2]==========:%d===============", carNum)

						trainInfo = fmt.Sprintf("TrainNumber %s  CarNumber %s ", active.TrainNum, active.TrainInfoMap[active.TrainNum][carNum])

						//lfshook.NewLogger().Infof("Train info=============%s===============", trainInfo)

						if len(caller) == 4 && len(caller) > 0 {
							utils.Logger.Printf("Train Information: %s, MessageType: PAD , LocationCode: %c, Connected: %s, RecordFileName:%s", trainInfo, caller[3], callee, DstFile)
						} else {
							utils.Logger.Printf("Train Information: %s, MessageType: PAD , RecordFileName:%s . Can not get caller and callee  !", trainInfo, DstFile)
						}

					} else if strings.Contains(event["FILENAME"], "C2C") {
						_, caller, _ := utils.GetPadInfo(event["FILENAME"])
						utils.Logger.Printf("Train Information: %s , MessageType: CabCab, Caller: %s, RecordFileName: %s", trainInfo, caller, DstFile)
					} else if strings.Contains(event["FILENAME"], "CPA") {
						_, caller, _ := utils.GetPadInfo(event["FILENAME"])
						utils.Logger.Printf("Train Information: %s , MessageType: CPA, Caller: %s, RecordFileName: %s", trainInfo, caller, DstFile)
					} else if strings.Contains(event["FILENAME"], "EMG") {
						utils.Logger.Printf("Train Information: %s , MessageType: EMG, RecordFileName: %s", trainInfo, DstFile)
					} else if strings.Contains(event["FILENAME"], "STN") {
						utils.Logger.Printf("Train Information: %s , MessageType: STN, RecordFileName: %s", trainInfo, DstFile)
					} else if strings.Contains(event["FILENAME"], "DCS") {
						utils.Logger.Printf("Train Information: %s , MessageType: DCS, RecordFileName: %s", trainInfo, DstFile)
					} else if strings.Contains(event["FILENAME"], "SPC") {
						utils.Logger.Printf("Train Information: %s , MessageType: SPC, RecordFileName: %s", trainInfo, DstFile)
					} else if strings.Contains(event["FILENAME"], "CHK") {
						utils.Logger.Printf("Train Information: %s , MessageType: Self Check, RecordFileName: %s", trainInfo, DstFile)
					} else if strings.Contains(event["FILENAME"], "TONE") {
						utils.Logger.Printf("Train Information: %s , MessageType: TONE Test, RecordFileName: %s", trainInfo, DstFile)
					} else if strings.Contains(event["FILENAME"], "PA") {
						_, caller, _ := utils.GetPadInfo(event["FILENAME"])
						utils.Logger.Printf("Train Information: %s , MessageType: PA, Caller: %s, RecordFileName: %s", trainInfo, caller, DstFile)
					}
				}

				//Get path & generate recording XML file
				path := filepath.Dir(event["FILENAME"])
				rcdFileName := filepath.Base(event["FILENAME"])
				xmlFileName := strings.Replace(rcdFileName, "wav", "xml", 1)
				xmlFilePath := path + "/" + xmlFileName

				lfshook.NewLogger().Infof("Train info= xml path============%s===============", xmlFilePath)
				err := active.GenerateXML(xmlFilePath)
				if err != nil {
					lfshook.NewLogger().Infof("Generate recording XML err:%+v", err)
				}

			} else {
				lfshook.NewLogger().Infof("No files to upload!!!")
				break
			}
		}

	case "Hangup":

		lfshook.NewLogger().Infof("%s", event["Event"])
		//OCC answer PAD, hangup, redirect the next PAD to OCC
		if utils.IsIO(event["CallerIDNum"]) && (event["ConnectedLineNum"] == "ano1" || event["ConnectedLineNum"] == "ano8") && event["Context"] == "default" {
			lfshook.NewLogger().Infof("Hangup OCC-PAD event: %+v", event)

			// OCC hangup detected, hangup other running channels
			InterruptRunningTask("PAD-OCC")
			time.Sleep(time.Millisecond * 100) //wait endpoimt release

			res, _ := QueueStatus("0301", "") // check OCC queue ,if empty PAD end
			if res == nil {
				return
			}

			if res.Calls == "0" { //OCC queue is empty
				alstatus.OccPad("end")
				priority.OCCAnswer = 0
				priority.PADOccStart = 0

				/*//clean confbridge
				taskTmp, _ := priority.RegistryTask.Get("PAD-OCC")
				ConfbridgeKick(taskTmp.ConfbridgeID, "all")

					//check resume
						priority.RegistryTask.StopAndUnregister("PAD-OCC")
						taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
						if ok {
							if taskName == "EMG" {
								EMGConfbridgeReinvite(task.ConfbridgeID)
							} else if taskName == "CPA" {
								CPAConfbridgeReinvite(task.ConfbridgeID)
							}
						}
				*/
				//break
			} else { //OCC queue is not empty

				time.Sleep(time.Millisecond * 100) //wait io idle
				//lfshook.NewLogger().Infof("====Start OCC-PAD===next==%+v", res)
				if active.ActivedCab == "1" && ExtenStatus("1411") == "Idle" { //check active and OCC status
					time.Sleep(time.Second)
					PADChan := ""

					if res.Entrys != nil {
						for _, chanEntry := range res.Entrys {
							lfshook.NewLogger().Infof("PAD answered by OCC1 pos:%s chan:%s", chanEntry.Position, chanEntry.Channel)
							if chanEntry.Position == "1" {
								PADChan = chanEntry.Channel
								break
							}
						}

						if PADChan != "" {
							Ext := strings.Split(strings.Split(res.Entrys[0].Channel, "/")[1], "-")[0]

							alstatus.AlarmStatus(Ext, "connect")
							go RedirectInQueue(PADChan, "1411", "pad-page-occ-icp", Ext) //PAD Page(OCC+ICPs)

							go Dial("0401", "0512", "pad-rule-pacus-occ", "ano1", "ano1", "1") // PACUs dial OCC1
						} else {
							lfshook.NewLogger().Infof("OCC-QueueStatus PADCchan NULL")
						}
					}
					break
				} else if active.ActivedCab == "8" && ExtenStatus("1481") == "Idle" {
					time.Sleep(time.Second)
					PADChan := ""

					if res.Entrys != nil {
						for _, chanEntry := range res.Entrys {
							lfshook.NewLogger().Infof("PAD answered by OCC1 pos:%s chan:%s", chanEntry.Position, chanEntry.Channel)
							if chanEntry.Position == "1" {
								PADChan = chanEntry.Channel
								break
							}
						}

						if PADChan != "" {
							Ext := strings.Split(strings.Split(res.Entrys[0].Channel, "/")[1], "-")[0]

							alstatus.AlarmStatus(Ext, "connect")
							go RedirectInQueue(PADChan, "1481", "pad-page-occ-icp", Ext) //PAD Page(OCC+ICPs)

							go Dial("0401", "0512", "pad-rule-pacus-occ", "ano8", "ano8", "8") // PACUs dial OCC1
						} else {
							lfshook.NewLogger().Infof("OCC QueueStatus PADCchan NULL")
						}
					}
					break
				}
			}
		}

		if utils.IsPAIU(event["CallerIDNum"]) { // PAD hangup, check if PAD all end, send PAD end status

			number := strings.Split(strings.Split(event["Channel"], "-")[0], "/")[1]

			//lfshook.NewLogger().Infof("===hangup PAD =======================%s", number)

			if utils.IsPAIU(number) {

				//clean confbridge & clean task info
				//PAD-ICP
				taskTmp, ok := priority.RegistryTask.Get("PAD-ICP")
				if ok {
					ConfbridgeKick(taskTmp.ConfbridgeID, "all")
					priority.RegistryTask.StopAndUnregister("PAD-ICP")
				}

				// PAD-TMS
				taskTmp, ok = priority.RegistryTask.Get("PAD-TMS")
				if ok {
					ConfbridgeKick(taskTmp.ConfbridgeID, "all")
					priority.RegistryTask.StopAndUnregister("PAD-TMS")
				}

				//PAD-OCC
				taskTmp, ok = priority.RegistryTask.Get("PAD-OCC")
				if ok {
					ConfbridgeKick(taskTmp.ConfbridgeID, "all")
					priority.RegistryTask.StopAndUnregister("PAD-OCC")
				}

				//Check PAD END
				res, _ := QueueStatus("0300", "")  // check ICP queue ,if empty PAD end
				res1, _ := QueueStatus("0301", "") // check OCC queue ,if empty PAD end
				if res == nil || res1 == nil {
					return
				}
				lfshook.NewLogger().Infof("===Hangup  PAD====== ICP Queue calls:%s  OCC Queue calls:%s", res.Calls, res1.Calls)
				if res.Calls == "0" && res1.Calls == "0" {

					if priority.PADStart == 1 {
						//SetPadTimer()
						alstatus.PaStatus("", "PAD", "end")
						priority.PADStart = 0
						//priority.PADTMSStart = 0
						/*
							//clean confbridge
							//PAD-ICP
							taskTmp, ok := priority.RegistryTask.Get("PAD-ICP")
							if ok {
								ConfbridgeKick(taskTmp.ConfbridgeID, "all")
							}
							priority.RegistryTask.StopAndUnregister("PAD-ICP")

							// PAD-TMS
							taskTmp, ok = priority.RegistryTask.Get("PAD-TMS")
							if ok {
								ConfbridgeKick(taskTmp.ConfbridgeID, "all")
							}
							priority.RegistryTask.StopAndUnregister("PAD-TMS")

							//PAD-OCC
							taskTmp, ok = priority.RegistryTask.Get("PAD-OCC")
							if ok {
								ConfbridgeKick(taskTmp.ConfbridgeID, "all")
							}
							priority.RegistryTask.StopAndUnregister("PAD-OCC")
						*/
						//check resume
						taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
						if ok {
							if taskName == "EMG" {
								EMGConfbridgeReinvite(task.ConfbridgeID)
								alstatus.PaStatus("", "EMG", "start")
							} else if taskName == "CPA" {
								CPAConfbridgeReinvite(task.ConfbridgeID)
								alstatus.PaStatus("", "CPA", "start")
							}
						}
					}

					priority.ICPAnswer = 0
					priority.OCCAnswer = 0
					break
				}
			}
		}

	case "QueueCallerJoin":
		lfshook.NewLogger().Infof("=========%s", event["Event"])

		if priority.OCCAnswer == 1 && event["Queue"] == "0300" { //New PAD Goto the OCC queue in the first time, if OCC answered
			alstatus.AlarmStatus(event["CallerIDNum"], "queue") //send status to STC
			go RedirectInQueue(event["CallerIDNum"], "0301", "queues-occ", event["CallerIDNum"])
			break
		}

		if utils.IsPAIU(event["CallerIDNum"]) && utils.IsPAIU(event["CallerIDName"]) && event["Queue"] == "0300" { // Alarm join the queue, PAD in the queue
			alstatus.AlarmStatus(event["CallerIDNum"], "queue") //send status to STC

			ICPQueue, err := QueueStatus("0300", "") // check ICP queue, get entries
			if err != nil {
				lfshook.NewLogger().Infof("ICP QueueStatus err:%+v", err)
				return
			}
			if ICPQueue == nil {
				return
			}
			if priority.ICPAnswer == 0 && ICPQueue.Calls == "1" { //ICP did not answer any first call to the ICP queue ; Ready to Set Occ Queue Timer
				toRunpriority := priority.GetPriorityByKey("PAD-ICP")

				time.Sleep(time.Millisecond * 500) //wait high priority task start
				_, taskTmp, ok := priority.RegistryTask.HighestPriorityRunningTask()
				if ok {
					//lfshook.NewLogger().Infof("=1==QueueCallerJoin===runing:%d=====toRun:=%d==Status:%s", taskTmp, toRunpriority, event["ChannelStateDesc"])
					if taskTmp.Priority < toRunpriority { //higher priority task running ,do not set timer
						break
					}
				}

				//lfshook.NewLogger().Infof("==2=QueueCallerJoin===runing:%d=====toRun:=%d==Status:%s", taskTmp, toRunpriority, event["ChannelStateDesc"])

				//if (priority.RunningTypePriority > toRunpriority || priority.RunningTypePriority == 0) && event["ChannelStateDesc"] != "Up" {
				//active.SetTimer = true
				//lfshook.NewLogger().Logger.Infof("=========Start PAD timer !=============")
				if active.QueueTimer != nil {
					if active.QueueTimer.Stop() {
						lfshook.NewLogger().Logger.Infof("=========Release PAD timer true !============")
					} else {
						lfshook.NewLogger().Logger.Infof("=========Release PAD timer false ! ============")
					}
				}
				lfshook.NewLogger().Logger.Infof("=========Start PAD timer !======%d=======", active.PADTimeout)
				active.QueueTimer = time.AfterFunc(time.Duration(active.PADTimeout)*time.Second, func() { // check the PAD 30s timeout
					//active.QueueTimer = time.AfterFunc(30*time.Second, func() { // check the PAD 30s timeout
					//if both not active , return
					if active.ActivedCab == "" {
						return
					}

					res, err := QueueStatus("0301", "") // check OCC queue , if empty OCC-PAD start
					if err != nil {
						lfshook.NewLogger().Infof("OCC QueueStatus err:%+v", err)
						return
					}
					if res == nil {
						return
					}

					if res.Calls == "0" { // OCC queue empty
						resCaller, err := QueueStatus("0300", "") // check ICP queue, get entries
						if err != nil {
							lfshook.NewLogger().Infof("ICP QueueStatus err:%+v", err)
							return
						}

						if resCaller.Entrys != nil {
							sort.Slice(resCaller.Entrys, func(i, j int) bool {
								return resCaller.Entrys[i].Position < resCaller.Entrys[j].Position
							})

							for _, caller := range resCaller.Entrys {
								priority.ICPAnswer = 0
								//lfshook.NewLogger().Infof("====QueueCallerJoin==QueueTimer===%s", event["Event"])
								lfshook.NewLogger().Infof("Redirect to 0301 extension:%s Pos:%s", caller.CallerIDNum, caller.Position)
								//order by pos
								RedirectInQueue(caller.CallerIDNum, "0301", "queues-occ", caller.CallerIDNum) // redirect All ICP-PAD redirect to OCC queue
								time.Sleep(time.Millisecond * 100)                                            //200 ms delay
							}
						}

						//==============test info =====================
						/*
							time.Sleep(2 * time.Second)
							occque, err1 := QueueStatus("0301", "") // check ICP queue, get entries
							if err1 != nil {
								lfshook.NewLogger().Infof("ICP QueueStatus err:%+v", err)
								return
							}

							for _, caller := range occque.Entrys {
								lfshook.NewLogger().Infof("Q301====666666=SetPadTimer= entry:%s=Pos:%s==", caller.CallerIDNum, caller.Position)
							}*/

					}
				})
			}

			break
		}

		//first PAD caller goto OCC
		//OCC dial PACUs;
		//PAD Page OCC+ICPs;
		if utils.IsPAIU(event["CallerIDNum"]) && event["Queue"] == "0301" && priority.OCCAnswer == 0 { // The first PAD to OCC ,caller is PAD

			if priority.CheckPriority("PAD-OCC") {
				InterruptRunningTask("PAD-OCC")    //PAD-OCC interrupt other
				time.Sleep(time.Millisecond * 100) //wait endpoimt release
				priority.OCCAnswer = 1

				time.Sleep(time.Millisecond * 300)

				if active.TrainDevide == 0 { //列车没有断开
					if active.ActivedCab == "1" && ExtenStatus("1411") == "Idle" { //check active and OCC status

						alstatus.AlarmStatus(event["CallerIDNum"], "connect")
						go RedirectInQueue(event["Channel"], "1411", "pad-page-occ-icp", event["CallerIDNum"]) //PAD Page(OCC+ICPs)
						go Dial("0401", "0512", "pad-rule-pacus-occ", "ano1", "ano1", "1")                     // PACUs dial OCC1

					} else if active.ActivedCab == "8" && ExtenStatus("1481") == "Idle" {

						alstatus.AlarmStatus(event["CallerIDNum"], "connect")
						go RedirectInQueue(event["Channel"], "1481", "pad-page-occ-icp", event["CallerIDNum"]) //PAD Page(OCC+ICPs)
						go Dial("0401", "0512", "pad-rule-pacus-occ", "ano8", "ano8", "8")                     // PACUs dial OCC8
					}
				} else { //列车断开模式下
					if active.ActivedCab == "1" && ExtenStatus("1411") == "Idle" { //check active and OCC status

						alstatus.AlarmStatus(event["CallerIDNum"], "connect")
						go RedirectInQueue(event["Channel"], "1411", "pad-page-occ-icp", event["CallerIDNum"]) //PAD Page(OCC+ICPs)
						go Dial("0401", "0512", "pad-rule-pacus-occ", "ano1", "ano1", "1")                     // PACUs dial OCC1

					} else if active.ActivedCab == "8" && ExtenStatus("1481") == "Idle" {

						alstatus.AlarmStatus(event["CallerIDNum"], "connect")
						go RedirectInQueue(event["Channel"], "1481", "pad-page-occ-icp", event["CallerIDNum"]) //PAD Page(OCC+ICPs)
						go Dial("0401", "0512", "pad-rule-pacus-occ", "ano8", "ano8", "8")                     // PACUs dial OCC8
					}
				}
			} else {
				lfshook.NewLogger().Infof("====PAD-OCC Priority false===")
			}
		}

	case "ConfbridgeJoin":
		lfshook.NewLogger().Infof("=========%+v", event["Event"])
		lfshook.NewLogger().Infof("=========%+v", event)
		//set priority and send PA status msg
		switch event["CallerIDName"] {
		case "EMG":
			if event["Exten"] == "0502" {
				//================================
				task := priority.TaskInfo{
					RunChannel:   event["Channel"],
					LocalChan:    event["Channel"],
					RunType:      "EMG",
					Priority:     priority.AllTasks.EMG.Priority,
					ConfbridgeID: event["Conference"],
					Running:      true,
				}
				priority.RegistryTask.Register("EMG", task)

				alstatus.PaStatus("", "EMG", "start")
				//check PAD timer
				if priority.AllTasks.PADOCC.Priority > priority.AllTasks.EMG.Priority {
					if active.QueueTimer != nil {
						if active.QueueTimer.Stop() {
							lfshook.NewLogger().Logger.Infof("=========Release PAD timer true !============")
						} else {
							lfshook.NewLogger().Logger.Infof("=========Release PAD timer false ! ============")
						}
					}
				}

				return
			}
		case "SPC":
			if event["Exten"] == "0505" {
				//================================
				task := priority.TaskInfo{
					RunChannel:   event["Channel"],
					LocalChan:    event["Channel"],
					RunType:      "SPC",
					Priority:     priority.AllTasks.SPC.Priority,
					ConfbridgeID: event["Conference"],
					Running:      true,
				}
				priority.RegistryTask.Register("SPC", task)
				alstatus.PaStatus("", "SPC", "start")

				//check PAD timer
				if priority.AllTasks.PADOCC.Priority > priority.AllTasks.SPC.Priority {
					if active.QueueTimer != nil {
						if active.QueueTimer.Stop() {
							lfshook.NewLogger().Logger.Infof("=========Release PAD timer true !============")
						} else {
							lfshook.NewLogger().Logger.Infof("=========Release PAD timer false ! ============")
						}
					}
				}

				return
			}
		case "DCS":
			if event["Exten"] == "0504" {
				//================================
				task := priority.TaskInfo{
					RunChannel:   event["Channel"],
					LocalChan:    event["Channel"],
					RunType:      "DCS",
					Priority:     priority.AllTasks.DCS.Priority,
					ConfbridgeID: event["Conference"],
					Running:      true,
				}
				priority.RegistryTask.Register("DCS", task)
				alstatus.PaStatus("", "DCS", "start")
				//check PAD timer
				if priority.AllTasks.PADOCC.Priority > priority.AllTasks.DCS.Priority {
					if active.QueueTimer != nil {
						if active.QueueTimer.Stop() {
							lfshook.NewLogger().Logger.Infof("=========Release PAD timer true !============")
						} else {
							lfshook.NewLogger().Logger.Infof("=========Release PAD timer false ! ============")
						}
					}
				}

				return
			}
		case "STN":
			if event["Exten"] == "0503" {

				//================================
				task := priority.TaskInfo{
					RunChannel:   event["Channel"],
					LocalChan:    event["Channel"],
					RunType:      "STN",
					Priority:     priority.AllTasks.STN.Priority,
					ConfbridgeID: event["Conference"],
					Running:      true,
				}
				priority.RegistryTask.Register("STN", task)
				alstatus.PaStatus("", "STN", "start")

				//check PAD timer
				if priority.AllTasks.PADOCC.Priority > priority.AllTasks.STN.Priority {
					if active.QueueTimer != nil {
						if active.QueueTimer.Stop() {
							lfshook.NewLogger().Logger.Infof("=========Release PAD timer true !============")
						} else {
							lfshook.NewLogger().Logger.Infof("=========Release PAD timer false ! ============")
						}
					}
				}

				return
			}
		case "CHK":
			if event["Exten"] == "0510" {

				//================================
				task := priority.TaskInfo{
					RunChannel:   event["Channel"],
					LocalChan:    event["Channel"],
					RunType:      "CHK",
					Priority:     priority.AllTasks.CHK.Priority,
					ConfbridgeID: event["Conference"],
					Running:      true,
				}
				priority.RegistryTask.Register("CHK", task)
				alstatus.PaStatus("", "CHK", "start")

				//check PAD timer
				if priority.AllTasks.PADOCC.Priority > priority.AllTasks.CHK.Priority {
					if active.QueueTimer != nil {
						if active.QueueTimer.Stop() {
							lfshook.NewLogger().Logger.Infof("=========Release PAD timer true !============")
						} else {
							lfshook.NewLogger().Logger.Infof("=========Release PAD timer false ! ============")
						}
					}
				}
				return
			}
		case "VOL": // tone-test
			if event["Exten"] == "0513" {
				//================================
				task := priority.TaskInfo{
					RunChannel:   event["Channel"],
					LocalChan:    event["Channel"],
					RunType:      "VOL",
					Priority:     priority.AllTasks.VOL.Priority,
					ConfbridgeID: event["Conference"],
					Running:      true,
				}
				priority.RegistryTask.Register("VOL", task)
				alstatus.PaStatus("", "VOL", "start")

				//check PAD timer
				if priority.AllTasks.PADOCC.Priority > priority.AllTasks.VOL.Priority {
					if active.QueueTimer != nil {
						if active.QueueTimer.Stop() {
							lfshook.NewLogger().Logger.Infof("=========Release PAD timer true !============")
						} else {
							lfshook.NewLogger().Logger.Infof("=========Release PAD timer false ! ============")
						}
					}
				}

				return
			}
		}
		/*
			//get confbridge id for join back to confbridge
			if event["Context"] == "pad-page-occ-icp" && utils.IsPAIU(event["CallerIDNum"]) {
				//active.ICPCONBID = event["Conference"] //pad-occ
				priority.AllTasks.PADOCC.ConfbridgeID = event["Conference"]
			}
		*/
		//Send PA start msg to STC
		if utils.IsICP(event["CallerIDNum"]) && event["Exten"] == "0500" { // PA start

			alstatus.PaStatus(event["CallerIDNum"], "PA", "start")
			//================================
			task := priority.TaskInfo{
				RunChannel:   event["Channel"],
				LocalChan:    event["Channel"],
				RunType:      "PA",
				Priority:     priority.AllTasks.PA.Priority,
				ConfbridgeID: event["Conference"],
				Running:      true,
			}
			priority.RegistryTask.Register("PA", task)

			//check PAD timer
			if priority.AllTasks.PADOCC.Priority > priority.AllTasks.PA.Priority {
				if active.QueueTimer != nil {
					if active.QueueTimer.Stop() {
						lfshook.NewLogger().Logger.Infof("=========Release PAD timer true !============")
					} else {
						lfshook.NewLogger().Logger.Infof("=========Release PAD timer false ! ============")
					}
				}
			}

			break
		} else if utils.IsIO(event["CallerIDNum"]) && event["Exten"] == "0501" { //CPA start

			alstatus.PaStatus(event["CallerIDNum"], "CPA", "start")
			//================================
			task := priority.TaskInfo{
				RunChannel:   event["Channel"],
				LocalChan:    event["Channel"],
				RunType:      "CPA",
				Priority:     priority.AllTasks.CPA.Priority,
				ConfbridgeID: event["Conference"],
				Running:      true,
			}
			priority.RegistryTask.Register("CPA", task)

			//check PAD timer
			if priority.AllTasks.PADOCC.Priority > priority.AllTasks.CPA.Priority {
				if active.QueueTimer != nil {
					if active.QueueTimer.Stop() {
						lfshook.NewLogger().Logger.Infof("=========Release PAD timer true !============")
					} else {
						lfshook.NewLogger().Logger.Infof("=========Release PAD timer false ! ============")
					}
				}
			}

			return
		}

		//ICP answer PAD;PACUs connected ICP
		//PAD chanspy ICP1
		//ICP8 call PAD
		if event["ConnectedLineNum"] == "ani1" && event["Exten"] == "0511" { //PAD answered by ICP; PACUs connected ICP1
			lfshook.NewLogger().Infof("====PAD answered by ICP1:%s=====", event["ConnectedLineName"])
			alstatus.AlarmStatus(event["ConnectedLineName"], "connect")

			//================================
			task := priority.TaskInfo{
				RunChannel:   event["Channel"],
				LocalChan:    event["Channel"],
				RunType:      "PAD-ICP",
				Priority:     priority.AllTasks.PADICP.Priority,
				ConfbridgeID: event["Conference"],
				Running:      true,
			}
			priority.RegistryTask.Register("PAD-ICP", task)
			lfshook.NewLogger().Infof("=========PAD-ICP answer==ListAll===%+v", priority.RegistryTask.ListAll())
			go RedirectInQueue(event["ConnectedLineName"], "2311", "chanspy-rule-whisper", event["ConnectedLineName"]) //PAD chanspy(EqW) ICP1

			if ExtenStatus("2381") == "Idle" {
				go Dial("0402", event["ConnectedLineName"], "call-pad-rule", event["ConnectedLineName"], event["ConnectedLineName"], "8") // PAD call ICP8
			}
		}
		if event["ConnectedLineNum"] == "ani8" && event["Exten"] == "0511" { //PAD ansered by ICP8; PACUs connected ICP8
			lfshook.NewLogger().Infof("====PAD answered by ICP8:%s=====", event["ConnectedLineName"])
			alstatus.AlarmStatus(event["ConnectedLineName"], "connect")

			//================================
			task := priority.TaskInfo{
				RunChannel:   event["Channel"],
				LocalChan:    event["Channel"],
				RunType:      "PAD-ICP",
				Priority:     priority.AllTasks.PADICP.Priority,
				ConfbridgeID: event["Conference"],
				Running:      true,
			}
			priority.RegistryTask.Register("PAD-ICP", task)
			lfshook.NewLogger().Infof("=========PAD-ICP answer==ListAll===%+v", priority.RegistryTask.ListAll())
			go RedirectInQueue(event["ConnectedLineName"], "2381", "chanspy-rule-whisper", event["ConnectedLineName"]) //PAD chanspy(EqW) ICP8

			if ExtenStatus("2311") == "Idle" {
				go Dial("0402", event["ConnectedLineName"], "call-pad-rule", event["ConnectedLineName"], event["ConnectedLineName"], "1") // PAD call ICP1
			}
			break
		}

		//OCC answer PAD;Set the task channel
		if utils.IsPAIU(event["CallerIDNum"]) && utils.IsIO(event["Exten"]) && event["Context"] == "pad-page-occ-icp" { //PAD Page OCC1+ICPs connected
			lfshook.NewLogger().Infof("====PAD answered by OCC:====")

			//================================
			task := priority.TaskInfo{
				RunChannel:   event["Channel"],
				LocalChan:    event["Channel"],
				RunType:      "PAD-OCC",
				Priority:     priority.AllTasks.PADOCC.Priority,
				ConfbridgeID: event["Conference"],
				Running:      true,
			}
			priority.RegistryTask.Register("PAD-OCC", task)

			break
		}

	case "ConfbridgeLeave":
		lfshook.NewLogger().Infof("=========%s", event["Event"])
		if utils.IsICP(event["CallerIDNum"]) && event["Exten"] == "0500" { // PA end

			alstatus.PaStatus(event["CallerIDNum"], "PA", "end")

			priority.RegistryTask.StopAndUnregister("PA")
			SetPadTimer()
			// check resume
			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
			if ok {
				if taskName == "EMG" {
					EMGConfbridgeReinvite(task.ConfbridgeID)
					alstatus.PaStatus("", "EMG", "start")
				} else if taskName == "CPA" {
					CPAConfbridgeReinvite(task.ConfbridgeID)
					alstatus.PaStatus("", "CPA", "start")
				}
			}

		} else if utils.IsIO(event["CallerIDNum"]) && event["Exten"] == "0501" { //CPA end

			alstatus.PaStatus(event["CallerIDNum"], "CPA", "end")

			//CPA
			taskTmp, ok := priority.RegistryTask.Get("CPA")
			if ok {
				ConfbridgeKick(taskTmp.ConfbridgeID, "all")
			}
			priority.RegistryTask.StopAndUnregister("CPA")
			SetPadTimer()
			//check resume
			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
			if ok {
				if taskName == "EMG" {
					EMGConfbridgeReinvite(task.ConfbridgeID)
					alstatus.PaStatus("", "EMG", "start")
				}
			}

			//lfshook.NewLogger().Infof("=========%s", event["Event"])
		} else if event["CallerIDName"] == "EMG" && event["Exten"] == "0502" { // EMG broadcast hangup

			alstatus.PaStatus("", "EMG", "end")

			//EMG
			taskTmp, ok := priority.RegistryTask.Get("EMG")
			if ok {
				ConfbridgeKick(taskTmp.ConfbridgeID, "all")
			}
			priority.RegistryTask.StopAndUnregister("EMG")
			SetPadTimer()
			//check resume
			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
			if ok {
				if taskName == "CPA" {
					CPAConfbridgeReinvite(task.ConfbridgeID)
				}
			}

		} else if event["CallerIDName"] == "STN" && event["Exten"] == "0503" {

			alstatus.PaStatus("", "STN", "end")

			//STN
			taskTmp, ok := priority.RegistryTask.Get("STN")
			if ok {
				ConfbridgeKick(taskTmp.ConfbridgeID, "all")
			}
			priority.RegistryTask.StopAndUnregister("STN")
			SetPadTimer()
			//check resume
			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
			if ok {
				if taskName == "CPA" {
					CPAConfbridgeReinvite(task.ConfbridgeID)
					alstatus.PaStatus("", "CPA", "start")
				} else if taskName == "EMG" {
					EMGConfbridgeReinvite(task.ConfbridgeID)
					alstatus.PaStatus("", "EMG", "start")
				}
			}

		} else if event["CallerIDName"] == "DCS" && event["Exten"] == "0504" {

			alstatus.PaStatus("", "DCS", "end")

			//DSC
			taskTmp, ok := priority.RegistryTask.Get("DCS")
			if ok {
				ConfbridgeKick(taskTmp.ConfbridgeID, "all")
			}
			priority.RegistryTask.StopAndUnregister("DCS")
			SetPadTimer()
			//check resume
			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
			if ok {
				if taskName == "CPA" {
					CPAConfbridgeReinvite(task.ConfbridgeID)
					alstatus.PaStatus("", "CPA", "start")
				} else if taskName == "EMG" {
					EMGConfbridgeReinvite(task.ConfbridgeID)
					alstatus.PaStatus("", "EMG", "start")
					//alstatus.PaStatus("", "EMG", "start")
				}
			}

		} else if event["CallerIDName"] == "SPC" && event["Exten"] == "0505" {

			alstatus.PaStatus("", "SPC", "end")

			//SPC
			taskTmp, ok := priority.RegistryTask.Get("SPC")
			if ok {
				ConfbridgeKick(taskTmp.ConfbridgeID, "all")
			}
			priority.RegistryTask.StopAndUnregister("SPC")
			SetPadTimer()
			//check resume
			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
			if ok {
				if taskName == "CPA" {
					CPAConfbridgeReinvite(task.ConfbridgeID)
					alstatus.PaStatus("", "CPA", "start")
				} else if taskName == "EMG" {
					EMGConfbridgeReinvite(task.ConfbridgeID)
					alstatus.PaStatus("", "EMG", "start")
				}
			}

		} else if event["CallerIDName"] == "CHK" && event["Exten"] == "0510" {

			alstatus.PaStatus("", "CHK", "end")

			//CHK
			taskTmp, ok := priority.RegistryTask.Get("CHK")
			if ok {
				ConfbridgeKick(taskTmp.ConfbridgeID, "all")
			}
			priority.RegistryTask.StopAndUnregister("CHK")
			SetPadTimer()
			//check resume
			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
			if ok {
				if taskName == "CPA" {
					CPAConfbridgeReinvite(task.ConfbridgeID)
					alstatus.PaStatus("", "CPA", "start")
				} else if taskName == "EMG" {
					EMGConfbridgeReinvite(task.ConfbridgeID)
					alstatus.PaStatus("", "EMG", "start")
				}
			}

		} else if event["CallerIDName"] == "VOL" && event["Exten"] == "0513" {

			alstatus.PaStatus("", "VOL", "end")

			//VOL
			taskTmp, ok := priority.RegistryTask.Get("VOL")
			if ok {
				ConfbridgeKick(taskTmp.ConfbridgeID, "all")
			}
			priority.RegistryTask.StopAndUnregister("VOL")
			SetPadTimer()
			//check resume
			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
			if ok {
				if taskName == "CPA" {
					CPAConfbridgeReinvite(task.ConfbridgeID)
					alstatus.PaStatus("", "CPA", "start")
				} else if taskName == "EMG" {
					EMGConfbridgeReinvite(task.ConfbridgeID)
					alstatus.PaStatus("", "EMG", "start")
				}
			}
		}

	case "DialEnd":
		//lfshook.NewLogger().Infof("=========%s", event["Event"])
		//Cab Cab start
		if utils.IsICP(event["CallerIDNum"]) && event["Exten"] == "0400" && event["DialStatus"] == "ANSWER" {
			//================================
			task := priority.TaskInfo{
				RunChannel:   event["Channel"],
				LocalChan:    event["Channel"],
				RunType:      "C2C",
				Priority:     priority.AllTasks.C2C.Priority,
				ConfbridgeID: "",
				Running:      true,
			}
			priority.RegistryTask.Register("C2C", task)

			alstatus.PaStatus(event["CallerIDNum"], "C2C", "start")

			//check PAD timer
			if priority.AllTasks.PADOCC.Priority > priority.AllTasks.C2C.Priority {
				if active.QueueTimer != nil {
					if active.QueueTimer.Stop() {
						lfshook.NewLogger().Logger.Infof("=========Release PAD timer true !============")
					} else {
						lfshook.NewLogger().Logger.Infof("=========Release PAD timer false ! ============")
					}
				}
			}

		} else if utils.IsICP(event["CallerIDNum"]) && utils.IsICP(event["ConnectedLineNum"]) && event["DialStatus"] == "NOANSWER" {

			//lfshook.NewLogger().Infof("===%s======%s", event["Event"], event["DialStatus"])

			time.Sleep(time.Millisecond * 300)

			//check resume
			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
			if ok {
				ICPConfbridgeReinvite(task.ConfbridgeID, taskName)
			}
		}

		//TMS Answer PAD (有时asterisk反馈的BridgeEnter事件有问题，根据dialend判断)
		if utils.IsPAIU(event["CallerIDName"]) && utils.IsPACU(event["CallerIDNum"]) && event["DialStatus"] == "ANSWER" && event["Exten"] == "0403" {
			lfshook.NewLogger().Infof("====BridgeEnter==IN action===%s===ID:%s   Name:%s", event["Event"], event["CallerIDNum"], event["CallerIDName"])
			alstatus.AlarmStatus(event["CallerIDName"], "connect") // Alarm connected

			//=============================
			task := priority.TaskInfo{
				RunChannel:   event["Channel"],
				LocalChan:    event["Channel"],
				RunType:      "PAD-TMS",
				Priority:     priority.AllTasks.PADTMS.Priority,
				ConfbridgeID: "",
				Running:      true,
			}
			priority.RegistryTask.Register("PAD-TMS", task)

			lfshook.NewLogger().Infof("=========PAD-TMS answer==ListAll===%+v", priority.RegistryTask.ListAll())

			if active.ActivedCab == "1" {
				go RedirectInQueue(event["CallerIDName"], "2311", "chanspy-rule-whisper", "") //PAD chanspy(EqW) ICP1
				go Dial("0403", event["CallerIDName"], "call-pad-rule", "2381", "2381", "8")  //ICP8---call----PAD
			} else if active.ActivedCab == "8" {
				go RedirectInQueue(event["CallerIDName"], "2381", "chanspy-rule-whisper", "") //PAD chanspy(EqW) ICP8
				go Dial("0403", event["CallerIDName"], "call-pad-rule", "2311", "2311", "1")  //ICP1---call----PAD
			} else if active.ActivedCab == "" {
				go RedirectInQueue(event["CallerIDName"], "2311", "chanspy-rule-whisper", "") //PAD chanspy(EqW) ICP1
				go Dial("0403", event["CallerIDName"], "call-pad-rule", "2381", "2381", "8")  //ICP8---call----PAD
			}
		}

	case "BridgeLeave":
		//lfshook.NewLogger().Infof("=========%s", event["Event"])
		//Cab Cab end
		if utils.IsICP(event["CallerIDNum"]) && utils.IsICP(event["ConnectedLineNum"]) && event["Exten"] == "0400" {

			alstatus.PaStatus(event["CallerIDNum"], "C2C", "end")
			priority.RegistryTask.StopAndUnregister("C2C")
			time.Sleep(time.Millisecond * 300)
			SetPadTimer()
			//check resume
			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
			if ok {
				ICPConfbridgeReinvite(task.ConfbridgeID, taskName)
				//check resume
				/*if taskName == "CPA" {
					alstatus.PaStatus("", "CPA", "start")
				} else if taskName == "EMG" {
					alstatus.PaStatus("", "EMG", "start")
				} else if taskName == "SPC" {
					alstatus.PaStatus("", "SPC", "start")
				} else if taskName == "DCS" {
					alstatus.PaStatus("", "DCS", "start")
				} else if taskName == "STN" {
					alstatus.PaStatus("", "STN", "start")
				} else if taskName == "CHK" {
					alstatus.PaStatus("", "CHK", "start")
				}*/
			}
		}

	case "ExtensionStatus":
		//lfshook.NewLogger().Infof("=========event:%s  Ext:%s status:%s ", event["Event"], event["Exten"], event["StatusText"])

		//update extension status
		if event["StatusText"] == "Idle" || event["StatusText"] == "Unavailable" {
			if len(event["Exten"]) > 3 && utils.IsPAIU(event["Exten"]) {
				alstatus.AlarmStatus(event["Exten"], event["StatusText"]) // PAD idle + unavailable
			}
		}

	case "BridgeEnter": // TMS-ICP answer PAD; PACU connect ICP
		lfshook.NewLogger().Infof("=========event:%s   callerid-num:%s callerid-name:%s", event["Event"], event["CallerIDNum"], event["CallerIDName"])

		//PAD-OCC start
		if utils.IsIO(event["CallerIDNum"]) && utils.IsPAIU(event["ConnectedLineNum"]) {
			if priority.PADOccStart == 0 {
				alstatus.OccPad("start")
				priority.PADOccStart = 1
			}

			if priority.PADStart == 0 {
				alstatus.PaStatus("", "PAD", "start")
				priority.PADStart = 1
			}
		}

		/*if utils.IsPACU(event["CallerIDNum"]) && utils.IsPAIU(event["CallerIDName"]) { //ICP and PACU connected -----TMS Answer PAD
			lfshook.NewLogger().Infof("====BridgeEnter==IN action===%s===ID:%s   Name:%s", event["Event"], event["CallerIDNum"], event["CallerIDName"])
			alstatus.AlarmStatus(event["CallerIDName"], "connect") // Alarm connected

			//=============================
			task := priority.TaskInfo{
				RunChannel:   event["Channel"],
				LocalChan:    event["Channel"],
				RunType:      "PAD-TMS",
				Priority:     priority.AllTasks.PADTMS.Priority,
				ConfbridgeID: "",
				Running:      true,
			}
			priority.RegistryTask.Register("PAD-TMS", task)

			lfshook.NewLogger().Infof("=========PAD-TMS answer==ListAll===%+v", priority.RegistryTask.ListAll())

			if active.ActivedCab == "1" {
				go RedirectInQueue(event["CallerIDName"], "2311", "chanspy-rule-whisper", "") //PAD chanspy(EqW) ICP1
				go Dial("0403", event["CallerIDName"], "call-pad-rule", "2381", "2381", "8")  //ICP8---call----PAD
			} else if active.ActivedCab == "8" {
				go RedirectInQueue(event["CallerIDName"], "2381", "chanspy-rule-whisper", "") //PAD chanspy(EqW) ICP8
				go Dial("0403", event["CallerIDName"], "call-pad-rule", "2311", "2311", "1")  //ICP1---call----PAD
			} else if active.ActivedCab == "" {
				go RedirectInQueue(event["CallerIDName"], "2311", "chanspy-rule-whisper", "") //PAD chanspy(EqW) ICP1
				go Dial("0403", event["CallerIDName"], "call-pad-rule", "2381", "2381", "8")  //ICP8---call----PAD
			}
		} else*/if utils.IsPAIU(event["CallerIDNum"]) && event["Exten"] == "0405" { // PAD connect ICP-TMS;PACU not available

			//=============================
			task := priority.TaskInfo{
				RunChannel:   event["Channel"],
				LocalChan:    event["Channel"],
				RunType:      "PAD-TMS",
				Priority:     priority.AllTasks.PADTMS.Priority,
				ConfbridgeID: "",
				Running:      true,
			}
			priority.RegistryTask.Register("PAD-TMS", task)
			lfshook.NewLogger().Infof("=========PAD-TMS answer==ListAll===%+v", priority.RegistryTask.ListAll())

			alstatus.AlarmStatus(event["CallerIDNum"], "connect") // PAD connect ICP-TMS
		}
	}
}

func StartAMI(connectOKCallBack func(), handleEvents []func(event map[string]string)) {
	lfshook.NewLogger().Info("Start AMI")
	settings := &amigo.Settings{
		Host:     configs.ConfigGlobal.AsteriskAMIHost,
		Port:     configs.ConfigGlobal.AsteriskAMIPort,
		Username: configs.ConfigGlobal.AsteriskAMIUser,
		Password: configs.ConfigGlobal.AsteriskAMISecret,
		LogLevel: logrus.ErrorLevel}
	//lfshook.NewLogger().Infof("ami setting: %+v", settings)
	AminInstance = amigo.New(settings, lfshook.NewLogger())
	AminInstance.EventOn(func(payload ...interface{}) {
		// lfshook.NewLogger().Infof("ami event on %+v", payload[0])
		event := payload[0].(map[string]string)

		go HandleAMI(event)

		for _, handle := range handleEvents {
			go handle(event)
		}

	})
	AminInstance.ConnectOn(func(payload ...interface{}) {
		//lfshook.NewLogger().Infof("ami connect on %+v", payload[0])
		if payload[0] == pkg.Connect_OK {

			connectOKCallBack()
		} else {
			lfshook.NewLogger().Errorf("ami connect failure %+v", payload)
			//active.Master = false
		}
	})
	AminInstance.Connect()
}

func Connected() bool {
	if AminInstance != nil {
		return AminInstance.Connected()
	}
	return false
}
