package mml

import (
	"encoding/json"
	"fmt"
	"io"
	"net"
	"net/http"
	"regexp"
	"strings"
	"time"

	"be.ems/lib/core/ctx"
	"be.ems/lib/global"
	"be.ems/lib/log"
	"be.ems/lib/mmlp"
	"be.ems/lib/services"
	"be.ems/restagent/config"
	tokenConst "be.ems/src/framework/constants/token"
	neModel "be.ems/src/modules/network_element/model"
	neService "be.ems/src/modules/network_element/service"
)

// const (
// 	//经过测试，linux下，延时需要大于100ms
// 	TIME_DELAY_AFTER_WRITE = 200
// 	TIME_DEAD_LINE         = 10
// )

type Response struct {
	Data []string `json:"data"`
}

type MMLRequest struct {
	MML []string `json:"mml"`
}

var (
	// MML interface
	UriMML        = config.DefaultUriPrefix + "/operationManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/mml"
	UriMML2       = config.DefaultUriPrefix + "/operationManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/mml2"
	UriMMLDiscard = config.DefaultUriPrefix + "/opeartionManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/mml"
	UriNeOmMml    = config.DefaultUriPrefix + "/omManagement/{apiVersion}/mml/{netype}/{neid}"
	UriOmMmlExt   = config.DefaultUriPrefix + "/{managedType}/{apiVersion}/elementType/OMC/objectType/mml"
	UriOmMmlInt   = config.DefaultUriPrefix + "/omManagement/{apiVersion}/mml/{neType}/{neId}"

	CustomUriMML      = config.UriPrefix + "/operationManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/mml"
	CustomUriMML2     = config.UriPrefix + "/operationManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/mml2"
	CustomUriNeOmMml  = config.UriPrefix + "/omManagement/{apiVersion}/mml/{netype}/{neid}"
	CustomUriOmMmlExt = config.UriPrefix + "/opeartionManagement/{apiVersion}/elementType/OMC/objectType/mml"
	CustomUriOmMmlInt = config.UriPrefix + "/omManagement/{apiVersion}/mml/{neType}/{neId}"
)

var (
	TIME_DELAY_AFTER_WRITE time.Duration = 200
	TIME_DEAD_LINE         time.Duration = 10
	WIN_ROW_SIZE           int16         = 200
	WIN_COL_SIZE           int16         = 120
	BUFFER_SIZE            int           = 65535
)

func InitMML() {
	if config.GetYamlConfig().MML.Sleep != 0 {
		TIME_DELAY_AFTER_WRITE = time.Duration(config.GetYamlConfig().MML.Sleep)
	}
	if config.GetYamlConfig().MML.DeadLine != 0 {
		TIME_DEAD_LINE = time.Duration(config.GetYamlConfig().MML.DeadLine)
	}
	WIN_ROW_SIZE = config.GetYamlConfig().MML.SizeRow
	WIN_COL_SIZE = config.GetYamlConfig().MML.SizeCol
	BUFFER_SIZE = config.GetYamlConfig().MML.BufferSize
}

func PostMML2ToNF(w http.ResponseWriter, r *http.Request) {
	log.Info("PostMML2ToNF processing... ")

	neType := ctx.GetParam(r, "elementTypeValue")
	neId := ctx.GetQuery(r, "ne_id")
	if neId == "" {
		log.Error("NOT FOUND ne_id")
		services.ResponseBadRequest400WrongParamValue(w)
		return
	}
	log.Debug("neType:", neType, "neId", neId)

	neInfoArr := neService.NewNeInfo.SelectList(neModel.NeInfo{NeType: neType, NeId: neId}, false, true)
	if len(neInfoArr) < 1 {
		services.ResponseInternalServerError500DatabaseOperationFailed(w)
		return
	}
	neInfo := neInfoArr[0]
	if neInfo.NeId != neId || neInfo.IP == "" || len(neInfo.Hosts) < 2 {
		services.ResponseWithJson(w, 200, map[string]any{
			"code": 0,
			"msg":  "neInfo not found",
		})
		return
	}
	telnetHost := neInfo.Hosts[1]

	buf := make([]byte, BUFFER_SIZE)
	var n int
	var mmlResult []string
	hostMML := fmt.Sprintf("%s:%d", telnetHost.Addr, telnetHost.Port)
	conn, err := net.Dial("tcp", hostMML)
	if err != nil {
		errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err)
		log.Error(errMsg)
		mmlResult = append(mmlResult, errMsg)
		response := Response{mmlResult}
		services.ResponseWithJson(w, http.StatusOK, response)
		return
	}
	defer conn.Close()

	// localAddr := conn.LocalAddr()
	// remoteAddr := conn.RemoteAddr()
	// if localAddr == nil || remoteAddr == nil {
	// 	errMsg := fmt.Sprintf("connect invalid: localAddr=%v, remoteAddr=%v", localAddr, remoteAddr)
	// 	log.Error(errMsg)
	// 	mmlResult = append(mmlResult, errMsg)
	// 	response := Response{mmlResult}
	// 	services.ResponseWithJson(w, http.StatusOK, response)
	// 	return
	// }

	// 发送窗口大小设置命令
	conn.Write([]byte{255, 251, 31}) // 发送WILL WINDOW SIZE
	conn.Write([]byte{
		255, 250, 31,
		byte(WIN_COL_SIZE >> 8), byte(WIN_COL_SIZE & 0xFF),
		byte(WIN_ROW_SIZE >> 8), byte(WIN_ROW_SIZE & 0xFF),
		255, 240,
	}) // 发送设置 WINDOW SIZE

	conn.SetDeadline(time.Now().Add(TIME_DEAD_LINE * time.Second))
	loginStr := fmt.Sprintf("%s\n%s\n", telnetHost.User, telnetHost.Password)
	_, err = conn.Write([]byte(loginStr))
	if err != nil {
		log.Error("Failed to write:", err)
		mmlResult = append(mmlResult, err.Error())
		response := Response{mmlResult}
		services.ResponseWithJson(w, http.StatusOK, response)
		return
	}

	time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

	n, err = conn.Read(buf[0:])
	if err != nil {
		log.Error("Failed to read:", err)
		mmlResult = append(mmlResult, err.Error())
		response := Response{mmlResult}
		services.ResponseWithJson(w, http.StatusOK, response)
		return
	}
	log.Trace(string(buf[0:n]))

	body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
	if err != nil {
		log.Error("Failed to ReadAll:", err)
		services.ResponseNotFound404UriNotExist(w, r)
		return
	}
	log.Trace("Body:", string(body))

	mmlRequest := new(MMLRequest)
	_ = json.Unmarshal(body, mmlRequest)

	for _, mml := range mmlRequest.MML {
		mmlCommand := fmt.Sprintf("%s\n", mml)
		_, err = conn.Write([]byte(mmlCommand))
		if err != nil {
			log.Error("Failed to write:", err)
			mmlResult = append(mmlResult, err.Error())
			// response := Response{mmlResult}
			// services.ResponseWithJson(w, http.StatusOK, response)
			// return
			continue
		}
		time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

		n, err = conn.Read(buf[0:])
		if err != nil {
			log.Error("Failed to read:", err)
			mmlResult = append(mmlResult, err.Error())
			// response := Response{mmlResult}
			// services.ResponseWithJson(w, http.StatusOK, response)
			// return
			continue
		}
		log.Trace(string(buf[0 : n-len(neType)-2]))
		re1 := regexp.MustCompile(`\x1B\[[0-9;]*[a-zA-Z]`) // 匹配包含␛的控制字符
		//re2 := regexp.MustCompile(`\x00`) // 匹配空字符
		re2 := regexp.MustCompile(`[\x00-\x08\x0B\x0C\x0E-\x1F\x7F\x1B]`) // 匹配空字符和包含␛的控制字符
		//re := regexp.MustCompile(`[\x00-\x1F\x7F]`)
		result := re1.ReplaceAllString(string(buf[0:n]), "")
		result = re2.ReplaceAllString(result, "")
		mmlResult = append(mmlResult, result)
	}

	response := Response{mmlResult}
	services.ResponseWithJson(w, http.StatusOK, response)
}

func PostMMLToNF(w http.ResponseWriter, r *http.Request) {
	log.Debug("PostMMLToNF processing... ")

	// token, err := services.CheckExtValidRequest(w, r)
	// if err != nil {
	// 	log.Error("Request error:", err)
	// 	return
	// }
	// 经过测试，linux下，延时需要大于100ms
	// var TIME_DELAY_AFTER_WRITE time.Duration = 200
	// var TIME_DEAD_LINE time.Duration = 10
	// if config.GetYamlConfig().MML.Sleep != 0 {
	// 	TIME_DELAY_AFTER_WRITE = time.Duration(config.GetYamlConfig().MML.Sleep)
	// }
	// if config.GetYamlConfig().MML.DeadLine != 0 {
	// 	TIME_DEAD_LINE = time.Duration(config.GetYamlConfig().MML.DeadLine)
	// }

	neType := ctx.GetParam(r, "elementTypeValue")
	neId := ctx.GetQuery(r, "ne_id")
	if neId == "" {
		log.Error("NOT FOUND ne_id")
		services.ResponseBadRequest400WrongParamValue(w)
		return
	}
	log.Debug("neType:", neType, "neId", neId)

	if strings.ToLower(neType) == "omc" {
		PostMMLToOMC(w, r)
		return
	}

	neInfoArr := neService.NewNeInfo.SelectList(neModel.NeInfo{NeType: neType, NeId: neId}, false, true)
	if len(neInfoArr) < 1 {
		services.ResponseInternalServerError500DatabaseOperationFailed(w)
		return
	}
	neInfo := neInfoArr[0]
	if neInfo.NeId != neId || neInfo.IP == "" || len(neInfo.Hosts) < 2 {
		services.ResponseWithJson(w, 200, map[string]any{
			"code": 0,
			"msg":  "neInfo not found",
		})
		return
	}
	telnetHost := neInfo.Hosts[1]

	var buf [20 * 1024]byte
	//buf := make([]byte, 0)
	var n int
	var mmlResult []string
	switch strings.ToLower(neType) {
	case "xxx":
		body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
		if err != nil {
			log.Error("io.ReadAll is failed:", err)
			services.ResponseNotFound404UriNotExist(w, r)
			return
		}
		log.Trace("Body:", string(body))

		mmlRequest := new(MMLRequest)
		_ = json.Unmarshal(body, mmlRequest)

		// n, err = conn.Read(buf[0:])
		// if err != nil {
		// 	log.Error("Failed to read:", err)
		// 	mmlResult = append(mmlResult, err.Error())
		// 	response := Response{mmlResult}
		// 	services.ResponseWithJson(w, http.StatusOK, response)
		// 	return
		// }
		// log.Debug(string(buf[0:n]))

		// hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port)
		// conn, err := net.Dial("tcp", hostMML)
		// if err != nil {
		// 	errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err)
		// 	log.Error(errMsg)
		// 	mmlResult = append(mmlResult, errMsg)
		// 	response := Response{mmlResult}
		// 	services.ResponseWithJson(w, http.StatusOK, response)
		// 	return
		// }
		// defer conn.Close()

		// conn.SetDeadline(time.Now().Add(10 * time.Second))
		// loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password)
		// _, err = conn.Write([]byte(loginStr))
		// if err != nil {
		// 	log.Error("Failed to write:", err)
		// 	mmlResult = append(mmlResult, err.Error())
		// 	response := Response{mmlResult}
		// 	services.ResponseWithJson(w, http.StatusOK, response)
		// 	return
		// }
		// time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

		// n, err = conn.Write([]byte(config.GetYamlConfig().MML.User + "\n"))
		// if err != nil {
		// 	log.Error("Failed to write:", err)
		// 	mmlResult = append(mmlResult, err.Error())
		// 	response := Response{mmlResult}
		// 	services.ResponseWithJson(w, http.StatusOK, response)
		// 	return
		// }
		// log.Debug(string(buf[0:n]))
		// time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

		// n, err = conn.Read(buf[0:])
		// if err != nil {
		// 	log.Error("Failed to read:", err)
		// 	mmlResult = append(mmlResult, err.Error())
		// 	response := Response{mmlResult}
		// 	services.ResponseWithJson(w, http.StatusOK, response)
		// 	return
		// }
		// log.Debug(string(buf[0:n]))

		// n, err = conn.Write([]byte(config.GetYamlConfig().MML.Password + "\n"))
		// if err != nil {
		// 	log.Error("Failed to write:", err)
		// 	mmlResult = append(mmlResult, err.Error())
		// 	response := Response{mmlResult}
		// 	services.ResponseWithJson(w, http.StatusOK, response)
		// 	return
		// }
		// log.Debug(string(buf[0:n]))

		// time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

		// n, err = conn.Read(buf[0:])
		// if err != nil {
		// 	log.Error("Failed to read:", err)
		// 	mmlResult = append(mmlResult, err.Error())
		// 	response := Response{mmlResult}
		// 	services.ResponseWithJson(w, http.StatusOK, response)
		// 	return
		// }
		// log.Debug(string(buf[0:n]))

		for _, mml := range mmlRequest.MML {
			hostMML := fmt.Sprintf("%s:%d", telnetHost.Addr, telnetHost.Port)
			conn, err := net.Dial("tcp", hostMML)
			if err != nil {
				errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err)
				log.Error(errMsg)
				mmlResult = append(mmlResult, errMsg)
				response := Response{mmlResult}
				services.ResponseWithJson(w, http.StatusOK, response)
				return
			}
			defer conn.Close()

			conn.SetDeadline(time.Now().Add(TIME_DEAD_LINE * time.Second))

			loginStr := fmt.Sprintf("%s\n%s\n", telnetHost.User, telnetHost.Password)
			_, err = conn.Write([]byte(loginStr))
			if err != nil {
				log.Error("Failed to write:", err)
				mmlResult = append(mmlResult, err.Error())
				//response := Response{mmlResult}
				//services.ResponseWithJson(w, http.StatusOK, response)
				//return
				continue
			}
			time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
			mmlCommand := fmt.Sprintf("%s\n", mml)
			log.Debug("mml command:", mmlCommand)
			_, err = conn.Write([]byte(mmlCommand))
			if err != nil {
				log.Error("Failed to write:", err)
				mmlResult = append(mmlResult, err.Error())
				//response := Response{mmlResult}
				//services.ResponseWithJson(w, http.StatusOK, response)
				//return
				continue
			}
			time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

			n, err = conn.Read(buf[0:])
			if err != nil {
				log.Error("Failed to read:", err)
				mmlResult = append(mmlResult, err.Error())
				//response := Response{mmlResult}
				//services.ResponseWithJson(w, http.StatusOK, response)
				//return
				continue
			}
			log.Trace(string(buf[0 : n-len(neType)-2]))

			re1 := regexp.MustCompile(`\x1B\[[0-9;]*[a-zA-Z]`) // 匹配包含␛的控制字符
			//re2 := regexp.MustCompile(`\x00`) // 匹配空字符
			re2 := regexp.MustCompile(`[\x00-\x08\x0B\x0C\x0E-\x1F\x7F\x1B]`) // 匹配空字符和包含␛的控制字符
			//re := regexp.MustCompile(`[\x00-\x1F\x7F]`)
			// upf telnet buffer只能读取一次，需要去掉前面的多余字符
			//result := re1.ReplaceAllString(string(buf[config.GetYamlConfig().MML.UpfHeaderLength:n-len(neType)-2]), "")
			result := re1.ReplaceAllString(string(buf[0:n-len(neType)-2]), "")
			result = re2.ReplaceAllString(result, "")
			mmlResult = append(mmlResult, result)
			conn.Close()
			//mmlResult = append(mmlResult, string(buf[0:n-len(neType)-2]))

			// can't read buffer from upf telnet server, so return ok always
			// mmlResult = append(mmlResult, "COMMAND OK\n")
		}
	case "ims":
		hostMML := fmt.Sprintf("%s:%d", telnetHost.Addr, telnetHost.Port)
		conn, err := net.Dial("tcp", hostMML)
		if err != nil {
			errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err)
			log.Error(errMsg)
			mmlResult = append(mmlResult, errMsg)
			response := Response{mmlResult}
			services.ResponseWithJson(w, http.StatusOK, response)
			return
		}
		defer conn.Close()

		// localAddr := conn.LocalAddr()
		// remoteAddr := conn.RemoteAddr()
		// if localAddr == nil || remoteAddr == nil {
		// 	errMsg := fmt.Sprintf("connect invalid: localAddr=%v, remoteAddr=%v", localAddr, remoteAddr)
		// 	log.Error(errMsg)
		// 	mmlResult = append(mmlResult, errMsg)
		// 	response := Response{mmlResult}
		// 	services.ResponseWithJson(w, http.StatusOK, response)
		// 	return
		// }
		conn.SetDeadline(time.Now().Add(TIME_DEAD_LINE * time.Second))

		_, err = conn.Write([]byte(telnetHost.User + "\r\n"))
		if err != nil {
			log.Error("Failed to write:", err)
			mmlResult = append(mmlResult, err.Error())
			response := Response{mmlResult}
			services.ResponseWithJson(w, http.StatusOK, response)
			return
		}
		time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

		n, err = conn.Read(buf[0:])
		if err != nil {
			log.Error("Failed to read:", err)
			mmlResult = append(mmlResult, err.Error())
			response := Response{mmlResult}
			services.ResponseWithJson(w, http.StatusOK, response)
			return
		}
		log.Trace(string(buf[0:n]))

		_, err = conn.Write([]byte(telnetHost.Password + "\r\n"))
		if err != nil {
			log.Error("Failed to write:", err)
			mmlResult = append(mmlResult, err.Error())
			response := Response{mmlResult}
			services.ResponseWithJson(w, http.StatusOK, response)
			return
		}
		time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

		// loginStr := fmt.Sprintf("%s\r\n%s\r\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password)
		// _, err = conn.Write([]byte(loginStr))
		// if err != nil {
		// 	log.Error("Failed to write:", err)
		// 	mmlResult = append(mmlResult, err.Error())
		// 	response := Response{mmlResult}
		// 	services.ResponseWithJson(w, http.StatusOK, response)
		// 	return
		// }
		// time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

		n, err = conn.Read(buf[0:])
		if err != nil {
			log.Error("Failed to read:", err)
			mmlResult = append(mmlResult, err.Error())
			response := Response{mmlResult}
			services.ResponseWithJson(w, http.StatusOK, response)
			return
		}
		log.Trace(string(buf[0 : n-len(neType)-2]))
		body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
		if err != nil {
			log.Error("io.ReadAll is failed:", err)
			services.ResponseNotFound404UriNotExist(w, r)
			return
		}
		log.Trace("Body:", string(body))

		mmlRequest := new(MMLRequest)
		_ = json.Unmarshal(body, mmlRequest)

		for _, mml := range mmlRequest.MML {
			mmlCommand := fmt.Sprintf("%s\r\n", mml)
			log.Debug("mml command:", mmlCommand)
			_, err = conn.Write([]byte(mmlCommand))
			if err != nil {
				log.Error("Failed to write:", err)
				mmlResult = append(mmlResult, err.Error())
				// response := Response{mmlResult}
				// services.ResponseWithJson(w, http.StatusOK, response)
				// return
				continue
			}
			time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

			n, err = conn.Read(buf[0:])
			if err != nil {
				log.Error("Failed to read:", err)
				mmlResult = append(mmlResult, err.Error())
				// response := Response{mmlResult}
				// services.ResponseWithJson(w, http.StatusOK, response)
				// return
				continue
			}
			log.Trace(string(buf[0 : n-len(neType)-2]))

			re1 := regexp.MustCompile(`\x1B\[[0-9;]*[a-zA-Z]`) // 匹配包含␛的控制字符
			//re2 := regexp.MustCompile(`\x00`) // 匹配空字符
			re2 := regexp.MustCompile(`[\x00-\x08\x0B\x0C\x0E-\x1F\x7F\x1B]`) // 匹配空字符和包含␛的控制字符
			//re := regexp.MustCompile(`[\x00-\x1F\x7F]`)
			result := re1.ReplaceAllString(string(buf[0:n-len(neType)-2]), "")
			result = re2.ReplaceAllString(result, "")
			mmlResult = append(mmlResult, result)
		}
	default:
		hostMML := fmt.Sprintf("%s:%d", telnetHost.Addr, telnetHost.Port)
		conn, err := net.Dial("tcp", hostMML)
		if err != nil {
			errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err)
			log.Error(errMsg)
			mmlResult = append(mmlResult, errMsg)
			response := Response{mmlResult}
			services.ResponseWithJson(w, http.StatusOK, response)
			return
		}
		defer conn.Close()

		// localAddr := conn.LocalAddr()
		// remoteAddr := conn.RemoteAddr()
		// if localAddr == nil || remoteAddr == nil {
		// 	errMsg := fmt.Sprintf("connect invalid: localAddr=%v, remoteAddr=%v", localAddr, remoteAddr)
		// 	log.Error(errMsg)
		// 	mmlResult = append(mmlResult, errMsg)
		// 	response := Response{mmlResult}
		// 	services.ResponseWithJson(w, http.StatusOK, response)
		// 	return
		// }

		conn.SetDeadline(time.Now().Add(TIME_DEAD_LINE * time.Second))
		loginStr := fmt.Sprintf("%s\n%s\n", telnetHost.User, telnetHost.Password)
		_, err = conn.Write([]byte(loginStr))
		if err != nil {
			log.Error("Failed to write:", err)
			mmlResult = append(mmlResult, err.Error())
			response := Response{mmlResult}
			services.ResponseWithJson(w, http.StatusOK, response)
			return
		}

		time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

		n, err = conn.Read(buf[0:])
		if err != nil {
			log.Error("Failed to read:", err)
			mmlResult = append(mmlResult, err.Error())
			response := Response{mmlResult}
			services.ResponseWithJson(w, http.StatusOK, response)
			return
		}
		log.Trace(string(buf[0:n]))

		body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
		if err != nil {
			log.Error("Failed to ReadAll:", err)
			services.ResponseNotFound404UriNotExist(w, r)
			return
		}
		log.Trace("Body:", string(body))

		mmlRequest := new(MMLRequest)
		_ = json.Unmarshal(body, mmlRequest)

		for _, mml := range mmlRequest.MML {
			mmlCommand := fmt.Sprintf("%s\n", mml)
			_, err = conn.Write([]byte(mmlCommand))
			if err != nil {
				log.Error("Failed to write:", err)
				mmlResult = append(mmlResult, err.Error())
				// response := Response{mmlResult}
				// services.ResponseWithJson(w, http.StatusOK, response)
				// return
				continue
			}
			time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

			n, err = conn.Read(buf[0:])
			if err != nil {
				log.Error("Failed to read:", err)
				mmlResult = append(mmlResult, err.Error())
				// response := Response{mmlResult}
				// services.ResponseWithJson(w, http.StatusOK, response)
				// return
				continue
			}
			log.Trace(string(buf[0 : n-len(neType)-2]))
			re1 := regexp.MustCompile(`\x1B\[[0-9;]*[a-zA-Z]`) // 匹配包含␛的控制字符
			//re2 := regexp.MustCompile(`\x00`) // 匹配空字符
			re2 := regexp.MustCompile(`[\x00-\x08\x0B\x0C\x0E-\x1F\x7F\x1B]`) // 匹配空字符和包含␛的控制字符
			//re := regexp.MustCompile(`[\x00-\x1F\x7F]`)
			result := re1.ReplaceAllString(string(buf[0:n-len(neType)-2]), "")
			result = re2.ReplaceAllString(result, "")
			mmlResult = append(mmlResult, result)
		}
	}

	response := Response{mmlResult}
	services.ResponseWithJson(w, http.StatusOK, response)
}

func PostMMLToOMC(w http.ResponseWriter, r *http.Request) {
	log.Debug("PostMMLToOMC processing... ")

	neType := "OMC" //ctx.GetParam(r, "elementTypeValue")
	neId := ctx.GetQuery(r, "ne_id")
	if neId == "" {
		log.Error("NOT FOUND ne_id")
		services.ResponseBadRequest400WrongParamValue(w)
		return
	}
	log.Debug("neType:", neType, "neId", neId)

	neInfoArr := neService.NewNeInfo.SelectList(neModel.NeInfo{NeType: neType, NeId: neId}, false, false)
	if len(neInfoArr) < 1 {
		services.ResponseInternalServerError500DatabaseOperationFailed(w)
		return
	}
	neInfo := neInfoArr[0]
	if neInfo.NeId != neId || neInfo.IP == "" {
		services.ResponseWithJson(w, 200, map[string]any{
			"code": 0,
			"msg":  "neInfo not found",
		})
		return
	}

	body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
	if err != nil {
		log.Error("io.ReadAll is failed:", err)
		services.ResponseNotFound404UriNotExist(w, r)
		return
	}
	log.Trace("Body:", string(body))

	hostUri := fmt.Sprintf("http://%s:%d", neInfo.IP, neInfo.Port)
	omcMmlVar := &mmlp.MmlVar{
		Version:       global.Version,
		Output:        mmlp.DefaultFormatType,
		MmlHome:       config.GetYamlConfig().MML.MmlHome,
		Limit:         50,
		User:          "",
		SessionToken:  "",                                  // 旧token
		Authorization: r.Header.Get(tokenConst.HEADER_KEY), // 请求Token
		HttpUri:       hostUri,
		UserAgent:     config.GetDefaultUserAgent(),
	}
	mmlRequest := new(MMLRequest)
	_ = json.Unmarshal(body, mmlRequest)

	var mmlResult []string
	mmlLine := strings.Join(mmlRequest.MML, ";")

	var mmlCmds []mmlp.MmlCommand
	if err = mmlp.ParseMMLCommand(mmlLine, &mmlCmds); err != nil {
		response := fmt.Sprintf("parse command error: %v\n", err)
		mmlResult = append(mmlResult, response)
	}

	for _, mmlCmd := range mmlCmds {
		output, err := mmlp.TransMml2HttpReq(omcMmlVar, &mmlCmd)
		if err != nil {
			response := fmt.Sprintf("translate MML command error: %v]\n", err)
			mmlResult = append(mmlResult, response)
		}
		mmlResult = append(mmlResult, string(*output))
	}

	response := Response{mmlResult}
	services.ResponseWithJson(w, http.StatusOK, response)
}
