package ue

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

	"be.ems/lib/config"
	"be.ems/lib/core/ctx"
	"be.ems/lib/dborm"
	"be.ems/lib/global"
	"be.ems/lib/log"
	"be.ems/lib/services"
	tokenConst "be.ems/src/framework/constants/token"
	neDataModel "be.ems/src/modules/network_data/model"
	neDataService "be.ems/src/modules/network_data/service"
	"be.ems/src/modules/network_element/model"
	neService "be.ems/src/modules/network_element/service"
	"github.com/go-resty/resty/v2"
	"github.com/gorilla/mux"
)

// N3iwfUEInfo N3IWF在线用户信息
type N3iwfUEInfo struct {
	IMSI string `json:"imsi"`

	NAI        string `json:"nai"`
	RegState   int    `json:"regState"`
	Activetime string `json:"activeTime"`
}

type N3iwfUEData struct {
	Data []N3iwfUEInfo `json:"data"`
}

var (
	UriNBState           = config.DefaultUriPrefix + "/ueManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/nbState"
	UriNBInfo            = config.DefaultUriPrefix + "/ueManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/nbInfo"
	UriSMFUEInfo         = config.DefaultUriPrefix + "/ueManagement/{apiVersion}/elementType/smf/objectType/ueInfo"
	UriIMSUEInfo         = config.DefaultUriPrefix + "/ueManagement/{apiVersion}/elementType/ims/objectType/ueInfo"
	UriUENum             = config.DefaultUriPrefix + "/ueManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/ueNum"
	UriPCFUser           = config.DefaultUriPrefix + "/ueManagement/{apiVersion}/elementType/pcf/objectType/ueInfo"
	UriPCFUserM          = config.DefaultUriPrefix + "/ueManagement/{apiVersion}/elementType/pcf/objectType/ueInfo/batch/{number}"
	UriPCFUserFileImport = config.DefaultUriPrefix + "/ueManagement/{apiVersion}/elementType/pcf/objectType/ueInfo/file/import"
	UriPCFUserFileExport = config.DefaultUriPrefix + "/ueManagement/{apiVersion}/elementType/pcf/objectType/ueInfo/file/export"
	UriNSSFAvailableAMFs = config.DefaultUriPrefix + "/ueManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/availableAMFs"
	UriNSSFSubscriptions = config.DefaultUriPrefix + "/ueManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/subscriptions"

	CustomUriNBState           = config.UriPrefix + "/ueManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/nbState"
	CustomUriNBInfo            = config.UriPrefix + "/ueManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/nbInfo"
	CustomUriSMFUEInfo         = config.UriPrefix + "/ueManagement/{apiVersion}/elementType/smf/objectType/ueInfo"
	CustomUriIMSUEInfo         = config.UriPrefix + "/ueManagement/{apiVersion}/elementType/ims/objectType/ueInfo"
	CustomUriUENum             = config.UriPrefix + "/ueManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/ueNum"
	CustomUriPCFUser           = config.UriPrefix + "/ueManagement/{apiVersion}/elementType/pcf/objectType/ueInfo"
	CustomUriPCFUserM          = config.UriPrefix + "/ueManagement/{apiVersion}/elementType/pcf/objectType/ueInfo/batch/{number}"
	CustomUriPCFUserFileImport = config.UriPrefix + "/ueManagement/{apiVersion}/elementType/pcf/objectType/ueInfo/file/import"
	CustomUriPCFUserFileExport = config.UriPrefix + "/ueManagement/{apiVersion}/elementType/pcf/objectType/ueInfo/file/export"
	CustomUriNSSFAvailableAMFs = config.UriPrefix + "/ueManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/availableAMFs"
	CustomUriNSSFSubscriptions = config.UriPrefix + "/ueManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/subscriptions"
)

var client = resty.New()

func init() {
	/*
		client.
			SetTimeout(10 * time.Second).
			SetRetryCount(1).
			SetRetryWaitTime(1 * time.Second).
			SetRetryMaxWaitTime(2 * time.Second).
			SetRetryAfter(func(client *resty.Client, resp *resty.Response) (time.Duration, error) {
				return 0, errors.New("quota exceeded")
			})
	*/
	client.SetTimeout(500 * time.Millisecond)
}

// Get AvailableAMFs from NSSF
func GetAvailableAMFsFromNSSF(w http.ResponseWriter, r *http.Request) {
	log.Info("GetAvailableAMFsFromNSSF processing... ")

	vars := mux.Vars(r)
	neType := vars["elementTypeValue"]
	if strings.ToLower(neType) != "nssf" {
		services.ResponseNotFound404UriNotExist(w, r)
		return
	}
	//neTypeLower := strings.ToLower(neType)
	var neId string
	neIds := services.GetParamsArrByName("neId", r)
	if len(neIds) == 1 {
		neId = neIds[0]
	} else {
		services.ResponseNotFound404UriNotExist(w, r)
		return
	}

	// token, err := services.CheckFrontValidRequest(w, r)
	// if err != nil {
	// 	log.Error("Request error:", err)
	// 	return
	// }
	// log.Debug("token:", token)

	neInfo, err := dborm.XormGetNeInfo(neType, neId)
	if err != nil {
		log.Error("Failed to XormGetNeInfo:", err)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	} else if neInfo == nil {
		err := global.ErrCMNotFoundTargetNE
		log.Error(global.ErrCMNotFoundTargetNE)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	}
	log.Trace("neInfo:", neInfo)

	hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
	requestURI2NF := fmt.Sprintf("%s%s", hostUri, r.RequestURI)

	log.Debug("requestURI2NF:", requestURI2NF)

	resp, err := client.R().
		EnableTrace().
		SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
		// SetHeaders(map[string]string{"accessToken": token}).
		SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
		SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
		Get(requestURI2NF)
	if err != nil {
		log.Error("Get system state from NF is failed:", err)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	} else {
		var response services.MapResponse
		_ = json.Unmarshal(resp.Body(), &response)
		services.ResponseWithJson(w, resp.StatusCode(), response)
		return
	}
}

// Get Subscriptions from NSSF
func GetSubscriptionsFromNSSF(w http.ResponseWriter, r *http.Request) {
	log.Info("GetSubscriptionsFromNSSF processing... ")

	vars := mux.Vars(r)
	neType := vars["elementTypeValue"]
	if strings.ToLower(neType) != "nssf" {
		services.ResponseNotFound404UriNotExist(w, r)
		return
	}
	//neTypeLower := strings.ToLower(neType)
	var neId string
	neIds := services.GetParamsArrByName("neId", r)
	if len(neIds) == 1 {
		neId = neIds[0]
	} else {
		services.ResponseNotFound404UriNotExist(w, r)
		return
	}

	// token, err := services.CheckFrontValidRequest(w, r)
	// if err != nil {
	// 	log.Error("Request error:", err)
	// 	return
	// }
	// log.Debug("token:", token)

	neInfo, err := dborm.XormGetNeInfo(neType, neId)
	if err != nil {
		log.Error("Failed to XormGetNeInfo:", err)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	} else if neInfo == nil {
		err := global.ErrCMNotFoundTargetNE
		log.Error(global.ErrCMNotFoundTargetNE)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	}
	log.Trace("neInfo:", neInfo)

	hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
	requestURI2NF := fmt.Sprintf("%s%s", hostUri, r.RequestURI)

	log.Debug("requestURI2NF:", requestURI2NF)

	resp, err := client.R().
		EnableTrace().
		SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
		// SetHeaders(map[string]string{"accessToken": token}).
		SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
		SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
		Get(requestURI2NF)
	if err != nil {
		log.Error("Get system state from NF is failed:", err)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	} else {
		var response services.MapResponse
		_ = json.Unmarshal(resp.Body(), &response)
		services.ResponseWithJson(w, resp.StatusCode(), response)
		return
	}
}

// SmfUEInfo SMF在线用户信息
type SmfUEInfo struct {
	IMSI           string `json:"imsi"`
	MSISDN         string `json:"msisdn"`
	RatType        string `json:"ratType"`
	PduSessionInfo []struct {
		PduSessionID int    `json:"pduSessionID"`
		IPv4         string `json:"ipv4"`
		IPv6         string `json:"ipv6"`
		Dnn          string `json:"dnn"`
		Tai          string `json:"tai"`
		SstSD        string `json:"sstSD"`
		UpfN3IP      string `json:"upfN3IP"`
		RanN3IP      string `json:"ranN3IP"`
		Activetime   string `json:"activeTime"`
		UpState      string `json:"upState"`
	} `json:"pduSessionInfo"`
}

type TenantUEInfo struct {
	NeType         string `json:"neType"`
	NeID           string `json:"neId"`
	IMSI           string `json:"imsi"`
	MSISDN         string `json:"msisdn"`
	RatType        string `json:"ratType"`
	PduSessionInfo []struct {
		PduSessionID int    `json:"pduSessionID"`
		IPv4         string `json:"ipv4"`
		IPv6         string `json:"ipv6"`
		Dnn          string `json:"dnn"`
		Tai          string `json:"tai"`
		SstSD        string `json:"sstSD"`
		UpfN3IP      string `json:"upfN3IP"`
		RanN3IP      string `json:"ranN3IP"`
		Activetime   string `json:"activeTime"`
		UpState      string `json:"upState"`
	} `json:"pduSessionInfo"`
	TenantName string `json:"tenantName"`
}

type SmfUEInfoResponse struct {
	Total int         `json:"total"`
	Data  []SmfUEInfo `json:"data"`
}

type UEInfoResponse struct {
	Total     int            `json:"total"`
	TenantNum int            `json:"tenantNum"`
	Data      []TenantUEInfo `json:"data"`
}

// Get UEInfo from NF/NFs, SMF Online users
func GetSMFUEInfoFromNF(w http.ResponseWriter, r *http.Request) {
	log.Debug("GetUEInfoFromNF processing... ")

	neId := ctx.GetQuery(r, "neId")
	neType := "smf"
	// if neType == "" || neId == "" {
	// 	log.Error("elementTypeValue/neId is empty")
	// 	services.ResponseNotFound404UriNotExist(w, r)
	// 	return
	// }
	var tenantName string
	tenantNames := services.GetParamsArrByName("tenantName", r)
	if len(tenantNames) > 0 {
		tenantName = tenantNames[0]
	}

	var neInfos []model.NeInfo
	if neId != "" {
		neInfo := neService.NewNeInfo.SelectNeInfoByNeTypeAndNeID(neType, neId)
		neInfos = append(neInfos, neInfo)
	} else {
		neInfos = neService.NewNeInfo.SelectNeInfoByNeType(neType)
	}

	var response UEInfoResponse
	for _, neInfo := range neInfos {
		//if neInfo.NeId == neId && neInfo.NeId != "" {
		requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.IP, neInfo.Port, r.RequestURI)
		//requestURI2NF := "http://127.0.0.1:4523/m1/3157310-1528434-default/api/rest/ueManagement/v1/elementType/smf/objectType/ueInfo?apifoxApiId=128609449"
		log.Debug("requestURI2NF:", requestURI2NF)
		resp, err := client.R().
			EnableTrace().
			SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
			SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
			Get(requestURI2NF)
		if err != nil {
			log.Error("Failed to Get from NF:", err)
			// services.ResponseInternalServerError500ProcessError(w, err)
			// return
			continue
		}
		// multi-tenancy solution
		var tenantID, where string
		//var cols []string
		if tenantName != "" {
			where = fmt.Sprintf("status='1' and tenant_name='%s'", tenantName)
			tenantID, _ = dborm.XormGetSingleColStringByWhere("sys_tenant", "tenant_id", where)
		} else {
			userName := ctx.LoginUserToUserName(r)
			where = fmt.Sprintf("status='1' and user_name='%s'", userName)
			tenantID, _ = dborm.XormGetSingleColStringByWhere("sys_user", "tenant_id", where)
			where = fmt.Sprintf("status='1' and tenant_id='%s'", tenantID)
			tenantName, _ = dborm.XormGetSingleColStringByWhere("sys_tenant", "tenant_name", where)
		}
		if tenantID == "" {
			var ueInfos UEInfoResponse
			_ = json.Unmarshal(resp.Body(), &ueInfos)
			response.Total = ueInfos.Total
			for i := 0; i < len(ueInfos.Data); i++ {
				where = fmt.Sprintf("status='1' and tenancy_type='IMSI' and '%s' like tenancy_key", ueInfos.Data[i].IMSI[5:])
				tenantID, _ = dborm.XormGetSingleColStringByWhere("sys_tenant", "parent_id", where)
				where = fmt.Sprintf("status='1' and tenant_id='%s'", tenantID)
				tenantName, _ = dborm.XormGetSingleColStringByWhere("sys_tenant", "tenant_name", where)
				log.Tracef("tenantName: %s tenantID: %s", tenantName, tenantID)
				ueInfos.Data[i].NeType = strings.ToUpper(neType)
				ueInfos.Data[i].NeID = neInfo.NeId
				ueInfos.Data[i].TenantName = tenantName
				response.Data = append(response.Data, ueInfos.Data[i])
			}
			// services.ResponseWithJson(w, resp.StatusCode(), &response)
			// return
		} else {
			//var tenantUEInfos []TenantUEInfo
			var ueInfos UEInfoResponse
			log.Trace("body:", string(resp.Body()))
			_ = json.Unmarshal(resp.Body(), &ueInfos)
			log.Trace("ueInfos:", ueInfos)
			for _, n := range ueInfos.Data {
				log.Trace("tenantID, n.IMSI[5:]:", tenantID, n.IMSI[5:])
				// "imsi": "imsi-460000100029999",
				where = fmt.Sprintf("status='1' and parent_id='%s' and tenancy_type='IMSI' and '%s' like tenancy_key", tenantID, n.IMSI[5:])
				has, err := dborm.XormExistTableOne("sys_tenant", where)
				if err == nil && has {
					n.NeType = strings.ToUpper(neType)
					n.NeID = neInfo.NeId
					n.TenantName = tenantName
					response.Data = append(response.Data, n)
					response.TenantNum++
				}
			}
			if ueInfos.Total > len(ueInfos.Data) {
				response.Total = ueInfos.Total
			} else {
				response.Total = response.TenantNum
			}
			// var response UEInfoResponse
			// response.Data = tenantUEInfos
			// services.ResponseWithJson(w, resp.StatusCode(), &response)
			// return
		}
	}

	services.ResponseWithJson(w, http.StatusOK, response)
}

// ImsUEInfo IMS在线用户信息
type ImsUEInfo struct {
	IMSI       string `json:"imsi"`
	MSISDN     string `json:"msisdn"`
	IMPU       string `json:"impu"`
	Barring    int    `json:"barring"`
	RegState   int    `json:"regState"`
	Activetime string `json:"activeTime"`
}

// ImsUEInfo IMS在线用户信息
type TenantImsUEInfo struct {
	NeType     string `json:"neType"`
	NeID       string `json:"neId"`
	IMSI       string `json:"imsi"`
	MSISDN     string `json:"msisdn"`
	IMPU       string `json:"impu"`
	Barring    int    `json:"barring"`
	RegState   int    `json:"regState"`
	Activetime string `json:"activeTime"`
	TenantName string `json:"tenantName"`
}

type ImsUEInfoResponse struct {
	Total int         `json:"total"`
	Data  []ImsUEInfo `json:"data"`
}

type TenantImsUEInfoResponse struct {
	Total int               `json:"total"`
	Data  []TenantImsUEInfo `json:"data"`
}

// Get UEInfo from NF/NFs, IMS Online users
func GetIMSUEInfoFromNF(w http.ResponseWriter, r *http.Request) {
	log.Debug("GetIMSUEInfoFromNF processing... ")

	neId := ctx.GetQuery(r, "neId")
	neType := "ims"
	// if neType == "" || neId == "" {
	// 	log.Error("elementTypeValue/neId is empty")
	// 	services.ResponseNotFound404UriNotExist(w, r)
	// 	return
	// }
	var tenantName string
	tenantNames := services.GetParamsArrByName("tenantName", r)
	if len(tenantNames) > 0 {
		tenantName = tenantNames[0]
	}

	var neInfos []model.NeInfo
	if neId != "" {
		neInfo := neService.NewNeInfo.SelectNeInfoByNeTypeAndNeID(neType, neId)
		neInfos = append(neInfos, neInfo)
	} else {
		neInfos = neService.NewNeInfo.SelectNeInfoByNeType(neType)
	}

	var response TenantImsUEInfoResponse
	for _, neInfo := range neInfos {
		requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.IP, neInfo.Port, r.RequestURI)
		//requestURI2NF := "http://127.0.0.1:4523/m1/3157310-1528434-default/api/rest/ueManagement/v1/elementType/ims/objectType/ueInfo?apifoxApiId=128609458"
		log.Debug("requestURI2NF:", requestURI2NF)
		resp, err := client.R().
			EnableTrace().
			SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
			SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
			Get(requestURI2NF)
		if err != nil {
			log.Error("Failed to Get from NF:", err)
			// services.ResponseInternalServerError500ProcessError(w, err)
			// return
			continue
		}
		// multi-tenancy solution
		var tenantID, where string
		//var cols []string
		if tenantName != "" {
			where = fmt.Sprintf("status='1' and tenant_name='%s'", tenantName)
			tenantID, _ = dborm.XormGetSingleColStringByWhere("sys_tenant", "tenant_id", where)
		} else {
			userName := ctx.LoginUserToUserName(r)
			where = fmt.Sprintf("status='1' and user_name='%s'", userName)
			tenantID, _ = dborm.XormGetSingleColStringByWhere("sys_user", "tenant_id", where)
			where = fmt.Sprintf("status='1' and tenant_id='%s'", tenantID)
			tenantName, _ = dborm.XormGetSingleColStringByWhere("sys_tenant", "tenant_name", where)
		}
		if tenantID == "" {
			var ueInfos TenantImsUEInfoResponse
			_ = json.Unmarshal(resp.Body(), &ueInfos)
			for i := 0; i < len(ueInfos.Data); i++ {
				where = fmt.Sprintf("status='1' and tenancy_type='IMSI' and '%s' like tenancy_key", ueInfos.Data[i].IMSI)
				tenantID, _ = dborm.XormGetSingleColStringByWhere("sys_tenant", "parent_id", where)
				where = fmt.Sprintf("status='1' and tenant_id='%s'", tenantID)
				tenantName, _ = dborm.XormGetSingleColStringByWhere("sys_tenant", "tenant_name", where)
				log.Tracef("tenantName: %s tenantID: %s", tenantName, tenantID)
				ueInfos.Data[i].NeType = strings.ToUpper(neType)
				ueInfos.Data[i].NeID = neInfo.NeId
				ueInfos.Data[i].TenantName = tenantName
				response.Data = append(response.Data, ueInfos.Data[i])
				response.Total = i
			}
			// services.ResponseWithJson(w, resp.StatusCode(), &response)
			// return
		} else {
			//var tenantUEInfos []TenantImsUEInfo
			var ueInfos TenantImsUEInfoResponse
			log.Trace("body:", string(resp.Body()))
			_ = json.Unmarshal(resp.Body(), &ueInfos)
			log.Trace("ueInfos:", ueInfos)
			for _, n := range ueInfos.Data {
				log.Trace("tenantID, n.IMSI:", tenantID, n.IMSI)
				// "imsi": "460000100029999",
				where = fmt.Sprintf("status='1' and parent_id='%s' and tenancy_type='IMSI' and '%s' like tenancy_key", tenantID, n.IMSI)
				has, err := dborm.XormExistTableOne("sys_tenant", where)
				if err == nil && has {
					n.NeType = strings.ToUpper(neType)
					n.NeID = neInfo.NeId
					n.TenantName = tenantName
					response.Data = append(response.Data, n)
					response.Total++
				}
			}
			// var response TenantImsUEInfoResponse
			// response.Data = tenantUEInfos
			// services.ResponseWithJson(w, resp.StatusCode(), &response)
			// return
		}
	}
	services.ResponseWithJson(w, http.StatusOK, response)
}

// Get UEInfo from NF/NFs, PCF Online users
func GetPCFUEInfoFromNF(w http.ResponseWriter, r *http.Request) {
	log.Debug("GetPCFUEInfoFromNF processing... ")

	neId := ctx.GetQuery(r, "neId")
	neType := "pcf"
	// if neType == "" || neId == "" {
	// 	log.Error("elementTypeValue/neId is empty")
	// 	services.ResponseNotFound404UriNotExist(w, r)
	// 	return
	// }

	neInfo := neService.NewNeInfo.SelectNeInfoByNeTypeAndNeID(neType, neId)

	var response services.MapResponse
	if neInfo.NeId == neId && neInfo.NeId != "" {
		requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.IP, neInfo.Port, r.RequestURI)
		log.Debug("requestURI2NF:", requestURI2NF)
		resp, err := client.R().
			EnableTrace().
			SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
			SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
			Get(requestURI2NF)
		if err != nil {
			log.Error("Failed to Get from NF:", err)
			services.ResponseInternalServerError500ProcessError(w, err)
			return
		} else {
			_ = json.Unmarshal(resp.Body(), &response)
		}
		log.Debug("response:", response)
	}

	services.ResponseWithJson(w, http.StatusOK, response)
}

// POST PCF User Info from NF/NFs
func PostPCFUserInfo(w http.ResponseWriter, r *http.Request) {
	log.Info("PostPCFUserInfo processing... ")

	// vars := mux.Vars(r)
	// neType := vars["elementTypeValue"]
	// if neType == "" {
	// 	services.ResponseNotFound404UriNotExist(w, r)
	// 	return
	// }
	//neTypeLower := strings.ToLower(neType)
	neType := "PCF"
	var neId string
	neIds := services.GetParamsArrByName("neId", r)
	if len(neIds) == 1 {
		neId = neIds[0]
	} else {
		services.ResponseNotFound404UriNotExist(w, r)
		return
	}

	// token, err := services.CheckFrontValidRequest(w, r)
	// if err != nil {
	// 	log.Error("Request error:", err)
	// 	return
	// }
	// log.Debug("token:", token)

	neInfo, err := dborm.XormGetNeInfo(neType, neId)
	if err != nil {
		log.Error("Failed to XormGetNeInfo:", err)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	} else if neInfo == nil {
		err := global.ErrCMNotFoundTargetNE
		log.Error(global.ErrCMNotFoundTargetNE)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	}
	log.Trace("neInfo:", neInfo)

	hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
	requestURI2NF := fmt.Sprintf("%s%s", hostUri, r.RequestURI)

	log.Debug("requestURI2NF:", requestURI2NF)

	body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) //io.LimitReader限制大小
	if err != nil {
		log.Error("io.ReadAll is failed:", err)
		services.ResponseNotFound404UriNotExist(w, r)
		return
	}
	client.SetTimeout(1 * time.Minute)
	resp, err := client.R().
		EnableTrace().
		SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
		//SetHeaders(map[string]string{"accessToken": token}).
		SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
		SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
		SetBody(body).
		Post(requestURI2NF)
	if err != nil {
		log.Error("Failed to post:", err)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	} else {
		var response services.MapResponse
		_ = json.Unmarshal(resp.Body(), &response)
		services.ResponseWithJson(w, resp.StatusCode(), response)
		return
	}
}

// PUT PCF User Info from NF/NFs
func PutPCFUserInfo(w http.ResponseWriter, r *http.Request) {
	log.Info("PutPCFUserInfo processing... ")

	// vars := mux.Vars(r)
	// neType := vars["elementTypeValue"]
	// if neType == "" {
	// 	services.ResponseNotFound404UriNotExist(w, r)
	// 	return
	// }
	//neTypeLower := strings.ToLower(neType)
	neType := "PCF"
	var neId string
	neIds := services.GetParamsArrByName("neId", r)
	if len(neIds) == 1 {
		neId = neIds[0]
	} else {
		services.ResponseNotFound404UriNotExist(w, r)
		return
	}

	// token, err := services.CheckFrontValidRequest(w, r)
	// if err != nil {
	// 	log.Error("Request error:", err)
	// 	return
	// }
	// log.Debug("token:", token)

	neInfo, err := dborm.XormGetNeInfo(neType, neId)
	if err != nil {
		log.Error("Failed to XormGetNeInfo:", err)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	} else if neInfo == nil {
		err := global.ErrCMNotFoundTargetNE
		log.Error(global.ErrCMNotFoundTargetNE)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	}
	log.Trace("neInfo:", neInfo)

	hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
	requestURI2NF := fmt.Sprintf("%s%s", hostUri, r.RequestURI)

	log.Debug("requestURI2NF:", requestURI2NF)

	body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) //io.LimitReader限制大小
	if err != nil {
		log.Error("io.ReadAll is failed:", err)
		services.ResponseNotFound404UriNotExist(w, r)
		return
	}
	client.SetTimeout(1 * time.Minute)
	resp, err := client.R().
		EnableTrace().
		SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
		//SetHeaders(map[string]string{"accessToken": token}).
		SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
		SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
		SetBody(body).
		Put(requestURI2NF)
	if err != nil {
		log.Error("Failed to put:", err)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	} else {
		var response services.MapResponse
		_ = json.Unmarshal(resp.Body(), &response)
		services.ResponseWithJson(w, resp.StatusCode(), response)
		return
	}
}

// Get UEInfo from NF/NFs
func DeletePCFUserInfo(w http.ResponseWriter, r *http.Request) {
	log.Info("DeletePCFUserInfo processing... ")

	// vars := mux.Vars(r)
	// neType := vars["elementTypeValue"]
	// if neType == "" {
	// 	services.ResponseNotFound404UriNotExist(w, r)
	// 	return
	// }
	//neTypeLower := strings.ToLower(neType)
	neType := "PCF"
	var neId string
	neIds := services.GetParamsArrByName("neId", r)
	if len(neIds) == 1 {
		neId = neIds[0]
	} else {
		services.ResponseNotFound404UriNotExist(w, r)
		return
	}

	// token, err := services.CheckFrontValidRequest(w, r)
	// if err != nil {
	// 	log.Error("Request error:", err)
	// 	return
	// }
	// log.Debug("token:", token)

	neInfo, err := dborm.XormGetNeInfo(neType, neId)
	if err != nil {
		log.Error("Failed to XormGetNeInfo:", err)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	} else if neInfo == nil {
		err := global.ErrCMNotFoundTargetNE
		log.Error(global.ErrCMNotFoundTargetNE)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	}
	log.Trace("neInfo:", neInfo)

	hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
	requestURI2NF := fmt.Sprintf("%s%s", hostUri, r.RequestURI)

	log.Debug("requestURI2NF:", requestURI2NF)

	resp, err := client.R().
		EnableTrace().
		SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
		//SetHeaders(map[string]string{"accessToken": token}).
		SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
		SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
		Delete(requestURI2NF)
	if err != nil {
		log.Error("Failed to delete:", err)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	} else {
		w.WriteHeader(resp.StatusCode())
		w.Write(resp.Body())
		// var response services.MapResponse
		// _ = json.Unmarshal(resp.Body(), &response)
		// services.ResponseWithJson(w, resp.StatusCode(), response)
		return
	}
}

// Get UEInfo from SMF
func GetUENumFromNF(w http.ResponseWriter, r *http.Request) {
	log.Info("GetUENumFromNF processing... ")

	vars := mux.Vars(r)
	neType := vars["elementTypeValue"]
	if neType == "" {
		services.ResponseNotFound404UriNotExist(w, r)
		return
	}
	//neTypeLower := strings.ToLower(neType)
	var neId string
	neIds := services.GetParamsArrByName("neId", r)
	if len(neIds) == 1 {
		neId = neIds[0]
	} else {
		services.ResponseNotFound404UriNotExist(w, r)
		return
	}

	// token, err := services.CheckFrontValidRequest(w, r)
	// if err != nil {
	// 	log.Error("Request error:", err)
	// 	return
	// }
	// log.Debug("token:", token)

	neInfo, err := dborm.XormGetNeInfo(neType, neId)
	if err != nil {
		log.Error("Failed to XormGetNeInfo:", err)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	} else if neInfo == nil {
		err := global.ErrCMNotFoundTargetNE
		log.Error(global.ErrCMNotFoundTargetNE)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	}
	log.Trace("neInfo:", neInfo)

	hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
	requestURI2NF := fmt.Sprintf("%s%s", hostUri, r.RequestURI)

	log.Debug("requestURI2NF:", requestURI2NF)

	resp, err := client.R().
		EnableTrace().
		SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
		// SetHeaders(map[string]string{"accessToken": token}).
		SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
		SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
		Get(requestURI2NF)
	if err != nil {
		log.Error("Get system state from NF is failed:", err)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	} else {
		var response services.MapResponse
		_ = json.Unmarshal(resp.Body(), &response)
		services.ResponseWithJson(w, resp.StatusCode(), response)
		return
	}
}

// SmfUENum SMF在线用户数
// type SmfUENum struct {
// 	UENum int `json:"ueNum"` // 当前在线用户数
// }

// UENumInfo IMS/SMF在线用户数
type UENumInfo struct {
	NeType string `json:"neType"`
	NeId   string `json:"neId"`
	Data   struct {
		UENum int `json:"ueNum"` // 当前在线用户数
	} `json:"data"`
}
type UENumResponse struct {
	UENums []UENumInfo
}

// Get UEInfo from SMF
func NewGetUENumFromNF(w http.ResponseWriter, r *http.Request) {
	log.Info("NewGetUENumFromNF processing... ")

	vars := mux.Vars(r)
	neType := vars["elementTypeValue"]
	if neType == "" {
		services.ResponseNotFound404UriNotExist(w, r)
		return
	}
	//neTypeLower := strings.ToLower(neType)
	//var neId string
	//neIds := services.GetParamsArrByName("neId", r)
	neId := ctx.GetQuery(r, "neId")
	// if len(neIds) == 1 {
	// 	neId = neIds[0]
	// } else {
	// 	services.ResponseNotFound404UriNotExist(w, r)
	// 	return
	// }

	// token, err := services.CheckFrontValidRequest(w, r)
	// if err != nil {
	// 	log.Error("Request error:", err)
	// 	return
	// }
	// log.Debug("token:", token)

	// neInfo, err := dborm.XormGetNeInfo(neType, neId)
	// if err != nil {
	// 	log.Error("Failed to XormGetNeInfo:", err)
	// 	services.ResponseInternalServerError500ProcessError(w, err)
	// 	return
	// } else if neInfo == nil {
	// 	err := global.ErrCMNotFoundTargetNE
	// 	log.Error(global.ErrCMNotFoundTargetNE)
	// 	services.ResponseInternalServerError500ProcessError(w, err)
	// 	return
	// }
	// log.Trace("neInfo:", neInfo)

	var neInfos []model.NeInfo
	if neId != "" {
		neInfo := neService.NewNeInfo.SelectNeInfoByNeTypeAndNeID(neType, neId)
		neInfos = append(neInfos, neInfo)
	} else {
		neInfos = neService.NewNeInfo.SelectNeInfoByNeType(neType)
	}

	var response []UENumInfo

	for _, neInfo := range neInfos {
		hostUri := fmt.Sprintf("http://%s:%v", neInfo.IP, neInfo.Port)
		requestURI2NF := fmt.Sprintf("%s%s", hostUri, r.RequestURI)

		log.Debug("requestURI2NF:", requestURI2NF)

		resp, err := client.R().
			EnableTrace().
			SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
			// SetHeaders(map[string]string{"accessToken": token}).
			SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
			SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
			Get(requestURI2NF)
		if err != nil {
			log.Error("failed to get UENum from NF:", err)
			services.ResponseInternalServerError500ProcessError(w, err)
			return
		} else {
			var ueNum UENumInfo
			_ = json.Unmarshal(resp.Body(), &ueNum)
			ueNum.NeType = strings.ToUpper(neType)
			ueNum.NeId = neInfo.NeId
			response = append(response, ueNum)
			// services.ResponseWithJson(w, resp.StatusCode(), response)
			// return
		}
	}
	if neId != "" {
		services.ResponseWithJson(w, http.StatusOK, response[0])
	} else {
		services.ResponseWithJson(w, http.StatusOK, response)
	}
}

// AmfNBInfo AMF的NodeB信息
type AmfNBInfo struct {
	ID      string `json:"id"`      //NodeB ID
	Name    string `json:"name"`    // NodeB name
	Address string `json:"address"` // 基站地址
	UENum   int    `json:"ueNum"`   // UE数量
}

type TenantNBInfo struct {
	ID         string `json:"id"`         //NodeB ID
	Name       string `json:"name"`       // NodeB name
	Address    string `json:"address"`    // 基站地址
	UENum      int    `json:"ueNum"`      // UE数量
	TenantName string `json:"tenantName"` // Tenant Name
}

type NBInfoResponse struct {
	Data []TenantNBInfo `json:"data"`
}

// Get AMF Radio Info from NF/NFs
func GetNBInfoFromNF(w http.ResponseWriter, r *http.Request) {
	log.Info("GetNBInfoFromNF processing... ")

	vars := mux.Vars(r)
	neType := vars["elementTypeValue"]
	if neType == "" {
		services.ResponseNotFound404UriNotExist(w, r)
		return
	}

	//neTypeLower := strings.ToLower(neType)
	var neId string
	neIds := services.GetParamsArrByName("neId", r)
	if len(neIds) == 1 {
		neId = neIds[0]
	} else {
		services.ResponseNotFound404UriNotExist(w, r)
		return
	}
	var tenantName string
	tenantNames := services.GetParamsArrByName("tenantName", r)
	if len(tenantNames) > 0 {
		tenantName = tenantNames[0]
	}
	// token, err := services.CheckFrontValidRequest(w, r)
	// if err != nil {
	// 	log.Error("Request error:", err)
	// 	return
	// }
	// log.Debug("token:", token)

	neInfo, err := dborm.XormGetNeInfo(neType, neId)
	if err != nil {
		log.Error("Failed to XormGetNeInfo:", err)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	} else if neInfo == nil {
		err := global.ErrCMNotFoundTargetNE
		log.Error(global.ErrCMNotFoundTargetNE)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	}
	log.Trace("neInfo:", neInfo)

	hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
	requestURI2NF := fmt.Sprintf("%s%s", hostUri, r.RequestURI)

	// for apifox mock test
	//requestURI2NF := "http://127.0.0.1:4523/m1/3157310-1528434-default/api/rest/ueManagement/v1/elementType/" + strings.ToLower(neType) + "/objectType/nbInfo?apifoxApiId=128848301"

	log.Debug("requestURI2NF:", requestURI2NF)

	resp, err := client.R().
		EnableTrace().
		SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
		// SetHeaders(map[string]string{"accessToken": token}).
		SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
		SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
		Get(requestURI2NF)
	if err != nil {
		log.Error("Get system state from NF is failed:", err)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	}

	// multi-tenancy solution
	var tenantID, where, userName, radioType string
	if strings.ToLower(neType) == "mme" {
		radioType = "4G"
	} else if strings.ToLower(neType) == "amf" {
		radioType = "5G"
	}
	if tenantName != "" {
		where = fmt.Sprintf("status='1' and tenant_name='%s'", tenantName)
		tenantID, _ = dborm.XormGetSingleColStringByWhere("sys_tenant", "tenant_id", where)
	} else {
		userName = ctx.LoginUserToUserName(r)
		where = fmt.Sprintf("status='1' and user_name='%s'", userName)
		tenantID, _ = dborm.XormGetSingleColStringByWhere("sys_user", "tenant_id", where)
		where = fmt.Sprintf("status='1' and tenant_id='%s'", tenantID)
		tenantName, _ = dborm.XormGetSingleColStringByWhere("sys_tenant", "tenant_name", where)
	}
	log.Tracef("tenantName: %s userName: %s tenantID: %s", tenantName, userName, tenantID)
	if tenantID == "" {
		var response NBInfoResponse
		//var nbInfo *TenantNBInfo
		_ = json.Unmarshal(resp.Body(), &response)

		for i := 0; i < len(response.Data); i++ {
			where = fmt.Sprintf("status='1' and tenancy_type='RADIO' and tenancy_key='%v'", radioType+"_"+response.Data[i].ID)
			tenantID, _ = dborm.XormGetSingleColStringByWhere("sys_tenant", "parent_id", where)
			where = fmt.Sprintf("status='1' and tenant_id='%s'", tenantID)
			tenantName, _ = dborm.XormGetSingleColStringByWhere("sys_tenant", "tenant_name", where)
			log.Tracef("tenantName: %s tenantID: %s", tenantName, tenantID)
			response.Data[i].TenantName = tenantName
		}
		services.ResponseWithJson(w, resp.StatusCode(), &response)
		return
	} else {
		// var response services.MapResponse
		var tenantNBInfos []TenantNBInfo
		var nbInfos NBInfoResponse
		var nbIDs []string
		// Get nodeB IDs by tenantID
		where = fmt.Sprintf("status='1' and tenancy_type='RADIO' and parent_id='%v'", tenantID)
		dborm.XormFindColStringArrayByWhere("sys_tenant", "tenancy_key", where, &nbIDs)
		_ = json.Unmarshal(resp.Body(), &nbInfos)
		for _, n := range nbInfos.Data {
			if global.IsMember(radioType+"_"+n.ID, nbIDs) {
				n.TenantName = tenantName
				tenantNBInfos = append(tenantNBInfos, n)
			}
		}
		log.Tracef("nbIDs: %v", nbIDs)
		nbInfos.Data = tenantNBInfos
		services.ResponseWithJson(w, resp.StatusCode(), &nbInfos)
		return
	}
}

// PostNBInfoFromNF 接收Radio数据请求
func PostNBInfoFromNF(w http.ResponseWriter, r *http.Request) {
	log.Info("PostNBInfoFromNF processing... ")
	neType := ctx.GetParam(r, "elementTypeValue")
	var body struct {
		NeType    string `json:"neType" `
		NeName    string `json:"neName" `
		RmUID     string `json:"rmUID"`
		StateList []struct {
			Address  string `json:"address" `
			Name     string `json:"name" `
			Position string `json:"position" `
			NbName   string `json:"nbName" `
			State    string `json:"state" `    // "OFF" or "ON"
			OffTime  string `json:"offTime"  ` //if State=OFF, will set it
			OnTime   string `json:"onTime"  `  //if State=ON , will set it
		}
	}
	if err := ctx.ShouldBindJSON(r, &body); err != nil {
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	}

	neTypeLower := strings.ToLower(body.NeType)
	if neType == "" || neType != neTypeLower {
		services.ResponseInternalServerError500ProcessError(w, fmt.Errorf("inconsistent network element types"))
		return
	}

	neInfo := neService.NewNeInfo.SelectNeInfoByRmuid(body.RmUID)
	if neInfo.RmUID != body.RmUID {
		services.ResponseInternalServerError500ProcessError(w, fmt.Errorf("inconsistent network element rmUID"))
		return
	}

	if len(body.StateList) == 0 {
		services.ResponseInternalServerError500ProcessError(w, fmt.Errorf("no stateList"))
		return
	}

	nbStateService := neDataService.NewNBState
	for _, v := range body.StateList {
		if v.Address == "" || v.State == "" {
			continue
		}
		timeStr := v.OffTime
		if v.State == "ON" {
			timeStr = v.OnTime
		}
		nbStateService.Insert(neDataModel.NBState{
			NeType:   neInfo.NeType,
			NeId:     neInfo.NeId,
			RmUid:    neInfo.RmUID,
			Address:  v.Address,
			Name:     v.Name,
			Position: v.Position,
			NbName:   v.NbName,
			State:    v.State,
			Time:     timeStr,
		})
	}

	services.ResponseStatusOK204NoContent(w)
}

// Get Radio Info from NF/NFs
func GetNBInfoAllFromNF(w http.ResponseWriter, r *http.Request) {
	log.Info("GetNBInfoAllFromNF processing... ")

	vars := mux.Vars(r)
	neType := vars["elementTypeValue"]
	if neType == "" {
		services.ResponseNotFound404UriNotExist(w, r)
		return
	}
	//neTypeLower := strings.ToLower(neType)
	// var neID string
	neIDs := services.GetParamsArrByName("neId", r)
	// if len(neIDs) == 1 {
	// 	neID = neIDs[0]
	// } else {
	// 	services.ResponseNotFound404UriNotExist(w, r)
	// 	return
	// }

	// token, err := services.CheckFrontValidRequest(w, r)
	// if err != nil {
	// 	log.Error("Request error:", err)
	// 	return
	// }
	// log.Debug("token:", token)

	//var ret error
	var statusCode int = 500
	var dataResponse []services.MapResponse
	var neInfos []dborm.NeInfo
	dborm.XormGetNeInfo2(neType, neIDs, &neInfos)
	for _, neInfo := range neInfos {
		// neInfo, err := dborm.XormGetNeInfo(neType, neID)
		// if err != nil {
		// 	log.Error("Failed to XormGetNeInfo:", err)
		// 	services.ResponseInternalServerError500ProcessError(w, err)
		// 	return
		// } else if neInfo == nil {
		// 	err := global.ErrCMNotFoundTargetNE
		// 	log.Error(global.ErrCMNotFoundTargetNE)
		// 	services.ResponseInternalServerError500ProcessError(w, err)
		// 	return
		// }

		hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
		requestURI2NF := fmt.Sprintf("%s%s", hostUri, r.RequestURI)

		log.Debug("requestURI2NF:", requestURI2NF)

		resp, err := client.R().
			EnableTrace().
			SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
			//SetHeaders(map[string]string{"accessToken": token}).
			SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
			SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
			Get(requestURI2NF)
		if err != nil {
			log.Error("Failed to GET:", err)
			continue
			// services.ResponseInternalServerError500ProcessError(w, err)
			// return
		} else {
			switch resp.StatusCode() {
			case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
				var response services.MapResponse
				_ = json.Unmarshal(resp.Body(), &response)
				dataResponse = append(dataResponse, response)
				statusCode = http.StatusOK
			}
		}
	}
	var response services.DataResponse
	response.Data = dataResponse
	services.ResponseWithJson(w, statusCode, response)
}

// Get GetUEInfoFileExportNF from NF/NFs
func GetUEInfoFileExportNF(w http.ResponseWriter, r *http.Request) {
	log.Info("GetUEInfoFromNF processing... ")

	// vars := mux.Vars(r)
	// neType := vars["elementTypeValue"]
	// if neType == "" {
	// 	services.ResponseNotFound404UriNotExist(w, r)
	// 	return
	// }
	//neTypeLower := strings.ToLower(neType)
	var neId string
	neIds := services.GetParamsArrByName("neId", r)
	if len(neIds) == 1 {
		neId = neIds[0]
	} else {
		services.ResponseNotFound404UriNotExist(w, r)
		return
	}

	// token, err := services.CheckFrontValidRequest(w, r)
	// if err != nil {
	// 	log.Error("Request error:", err)
	// 	return
	// }
	// log.Debug("token:", token)

	neInfo, err := dborm.XormGetNeInfo("PCF", neId)
	if err != nil {
		log.Error("Failed to XormGetNeInfo:", err)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	} else if neInfo == nil {
		err := global.ErrCMNotFoundTargetNE
		log.Error(global.ErrCMNotFoundTargetNE)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	}
	log.Trace("neInfo:", neInfo)

	hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
	requestURI2NF := fmt.Sprintf("%s%s", hostUri, r.RequestURI)

	log.Debug("requestURI2NF:", requestURI2NF)

	client.SetTimeout(3 * time.Minute)
	resp, err := client.R().
		EnableTrace().
		SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
		// SetHeaders(map[string]string{"accessToken": token}).
		SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
		SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
		Get(requestURI2NF)
	if err != nil {
		log.Error("Get system state from NF is failed:", err)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	} else {
		w.WriteHeader(resp.StatusCode())
		w.Write(resp.Body())
		// var response services.MapResponse
		// _ = json.Unmarshal(resp.Body(), &response)
		// services.ResponseWithJson(w, resp.StatusCode(), response)
		return
	}
}
