package utils

import (
	"flag"
	"fmt"
	"math/rand"
	"net"
	"os"
	"pbx-api-gin/pkg/lfshook"
	"strings"
	"time"
)

// IsFlagPassed 判断是否设置了指定 flag
func IsFlagPassed(name string) bool {
	found := false
	flag.Visit(func(f *flag.Flag) {
		if f.Name == name {
			found = true
		}
	})
	return found
}

// NumberOrStringToBool 字符串 1, yes 返回 true 否则 false
func NumberOrStringToBool(input string) bool {
	if input == "1" {
		return true
	}
	if input == "yes" {
		return true
	}
	return false
}

// NumberToBool 大于0 返回 true 否则 false
func NumberToBool(input int64) bool {
	if input > 0 {
		return true
	} else {
		return false
	}
}

// Bool to int true 返回 1 否则 0
func BoolToInt(input bool) int64 {
	var output int64
	if input {
		output = 1
	} else {
		output = 0
	}
	return output
}

// BoolToNumber true 返回 "1" false 返回  "0"
func BoolToNumber(input bool) string {
	if input {
		return "1"
	}
	return "0"
}

// BoolToString true 返回 "yes" false 返回  "no"
func BoolToString(input bool) string {
	if input {
		return "yes"
	}
	return "no"
}

// YesToOn  Yes 或 yes 返回 "on" 否则返回 "off"
// 会议 Muted 的值可能是 By admin
func YesToOn(input string) string {
	if input == "Yes" || input == "yes" || strings.Contains(input, "By") {
		return "on"
	}
	return "off"
}

// GetRandStr 生成随机密码
func GetRandStr(baseStr string, length int) string {
	r := rand.New(rand.NewSource(time.Now().UnixNano() + rand.Int63()))
	bytes := make([]byte, length)
	l := len(baseStr)
	for i := 0; i < length; i++ {
		bytes[i] = baseStr[r.Intn(l)]
	}
	return string(bytes)
}

// SqlLike sql like 头尾添加 %%
func SqlLike(input string) string {
	return fmt.Sprintf("%%%s%%", input)
}

// IsChannel 判断输入是否是 Channel
func IsChannel(input string) bool {
	if strings.Contains(input, "SIP") {
		return true
	}

	if strings.Contains(input, "Local") {
		return true
	}

	if strings.Contains(input, "DAHDI") {
		return true
	}
	return false
}

// 判断是否是广播分机
func IsPAIU(input string) bool {
	if len(input) == 4 {
		return input[:2] == "24"
	}
	return false
}

// 判断是否是广播分机
func IsPACU(input string) bool {
	if len(input) == 4 {
		return input[:2] == "21"
	}
	return false
}

// 判断是否是司机控制盒
func IsIO(input string) bool {

	if len(input) == 4 {
		return input[:2] == "14"
	}
	return false
}

// 判断是否是司机控制盒
func IsICP(input string) bool {

	if len(input) == 4 {
		return input[:2] == "23"
	}
	return false
}

// 根据PAD号码获取PACU号码
func GetPacuByPad(input string) string {

	if len(input) == 4 && input[:2] == "24" {
		return fmt.Sprintf("21%c1", input[2])
	} else {
		return ""
	}
}

// 判断文件是否存在
func PathExists(path string) bool {
	_, err := os.Stat(path)
	if err == nil {
		return true
	}
	if os.IsNotExist(err) {
		return false
	}
	return false
}

func IndexOf(sliceID []string, value string) int {
	for i, v := range sliceID {
		if v == value {
			return i
		}
	}
	return -1
}

func CheckAsterisk() bool {
	target := "127.0.0.1:5060"
	count := 2
udpDial:
	conn, err := net.DialTimeout("udp", target, 1*time.Second)
	if err != nil {
		return false
	}
	defer conn.Close()

	// 构造最小 SIP OPTIONS 请求（RFC 3261）
	req := "OPTIONS sip:test@" + target + " SIP/2.0\r\n" +
		"Via: SIP/2.0/UDP 127.0.0.1:5061;branch=z9hG4bK123456\r\n" +
		"Max-Forwards: 70\r\n" +
		"To: <sip:test@" + target + ">\r\n" +
		"From: <sip:probe@127.0.0.1>;tag=abc123\r\n" +
		"Call-ID: 123456789@127.0.0.1\r\n" +
		"CSeq: 1 OPTIONS\r\n" +
		"Contact: <sip:probe@127.0.0.1:5061>\r\n" +
		"Accept: application/sdp\r\n" +
		"Content-Length: 0\r\n\r\n"

	_, err = conn.Write([]byte(req))
	if err != nil {
		time.Sleep(time.Second)
		_, err = conn.Write([]byte(req))
		if err != nil {
			return false
		}
	}

	time.Sleep(time.Millisecond * 500)
	//conn.SetReadDeadline(time.Now().Add(1 * time.Second))
	buf := make([]byte, 2048)
	n, err := conn.Read(buf)
	if err != nil || n == 0 {
		count--
		lfshook.NewLogger().Logger.Infof("=====CheckAsterisk response==err==count:%d ", count)
		if count > 0 {
			time.Sleep(time.Millisecond * 500)
			goto udpDial
		}
		return false
	}
	resp := string(buf[:n])

	return strings.HasPrefix(resp, "SIP/2.0")
}
