package service

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"time"

	"be.ems/src/framework/cmd"
	"be.ems/src/framework/constants"
	"be.ems/src/framework/database/redis"
	"be.ems/src/framework/logger"
	"be.ems/src/framework/ssh"
	"be.ems/src/framework/telnet"
	"be.ems/src/framework/utils/file"
	"be.ems/src/framework/utils/generate"
	"be.ems/src/framework/utils/parse"
	neFetchlink "be.ems/src/modules/ne/fetch_link"
	"be.ems/src/modules/ne/model"
	"be.ems/src/modules/ne/repository"
)

// 实例化服务层 NeInfo 结构体
var NewNeInfo = &NeInfo{
	neInfoRepository: repository.NewNeInfo,
	neHostService:    NewNeHost,
	Para5GData:       map[string]string{},
}

// 网元信息 服务层处理
type NeInfo struct {
	neInfoRepository *repository.NeInfo // 网元信息数据信息
	neHostService    *NeHost            // 网元主机连接服务
	Para5GData       map[string]string
}

// FindByNeTypeAndNeID 通过ne_type和ne_id查询网元信息
func (r NeInfo) FindByNeTypeAndNeID(neType, neID string) model.NeInfo {
	var neInfo model.NeInfo
	key := fmt.Sprintf("%s:%s:%s", constants.CACHE_NE_INFO, strings.ToUpper(neType), neID)
	jsonStr, _ := redis.Get("", key)
	if len(jsonStr) > 7 {
		err := json.Unmarshal([]byte(jsonStr), &neInfo)
		if err != nil {
			neInfo = model.NeInfo{}
		}
	} else {
		neInfo = r.neInfoRepository.SelectNeInfoByNeTypeAndNeID(neType, neID)
		if neInfo.ID != 0 && neInfo.NeId == neID {
			redis.Del("", key)
			values, _ := json.Marshal(neInfo)
			redis.Set("", key, string(values), 0)
		}
	}
	return neInfo
}

// RefreshByNeTypeAndNeID 通过ne_type和ne_id刷新redis中的缓存
func (r NeInfo) RefreshByNeTypeAndNeID(neType, neID string) model.NeInfo {
	var neInfo model.NeInfo
	key := fmt.Sprintf("%s:%s:%s", constants.CACHE_NE_INFO, strings.ToUpper(neType), neID)
	redis.Del("", key)
	neInfo = r.neInfoRepository.SelectNeInfoByNeTypeAndNeID(neType, neID)
	if neInfo.ID != 0 && neInfo.NeId == neID {
		values, _ := json.Marshal(neInfo)
		redis.Set("", key, string(values), 0)
	}
	return neInfo
}

// ClearNeCacheByNeType 清除网元类型缓存
func (r NeInfo) ClearNeCacheByNeType(neType string) bool {
	key := fmt.Sprintf("%s:*", constants.CACHE_NE_INFO)
	if neType != "*" {
		key = fmt.Sprintf("%s:%s*", constants.CACHE_NE_INFO, neType)
	}
	keys, err := redis.GetKeys("", key)
	if err != nil {
		return false
	}
	return redis.DelKeys("", keys) == nil
}

// FindByNeType 通过ne_type查询网元信息
func (r NeInfo) FindByNeType(neType string) []model.NeInfo {
	neInfo := make([]model.NeInfo, 0)
	key := fmt.Sprintf("%s:%s:*", constants.CACHE_NE_INFO, strings.ToUpper(neType))
	cacheKeys, _ := redis.GetKeys("", key)
	if len(cacheKeys) > 0 {
		for _, key := range cacheKeys {
			var v model.NeInfo
			jsonStr, _ := redis.Get("", key)
			if len(jsonStr) > 7 {
				json.Unmarshal([]byte(jsonStr), &v)
			}
			neInfo = append(neInfo, v)
		}
		return neInfo
	} else {
		neInfo = r.neInfoRepository.SelectList(model.NeInfo{NeType: neType})
		for _, v := range neInfo {
			key := fmt.Sprintf("%s:%s:%s", constants.CACHE_NE_INFO, strings.ToUpper(v.NeType), v.NeId)
			redis.Del("", key)
			values, _ := json.Marshal(v)
			redis.Set("", key, string(values), 0)
		}
	}
	return neInfo
}

// FindByRmuid 通过rmUID查询网元信息
func (r NeInfo) FindByRmuid(rmUid string) model.NeInfo {
	var neInfo model.NeInfo
	cacheKeys, _ := redis.GetKeys("", constants.CACHE_NE_INFO+":*")
	if len(cacheKeys) > 0 {
		for _, key := range cacheKeys {
			var v model.NeInfo
			jsonStr, _ := redis.Get("", key)
			if len(jsonStr) > 7 {
				json.Unmarshal([]byte(jsonStr), &v)
			}
			if v.RmUID == rmUid {
				neInfo = v
				break
			}
		}
	} else {
		neInfos := r.Find(neInfo, false, false)
		for _, v := range neInfos {
			key := fmt.Sprintf("%s:%s:%s", constants.CACHE_NE_INFO, strings.ToUpper(v.NeType), v.NeId)
			redis.Del("", key)
			values, _ := json.Marshal(v)
			redis.Set("", key, string(values), 0)
			if v.RmUID == rmUid {
				neInfo = v
			}
		}
	}
	return neInfo
}

// FindByPage 根据条件分页查询
//
// bandStatus 带状态信息
func (r NeInfo) FindByPage(query map[string]string, bandStatus bool) ([]model.NeInfo, int64) {
	rows, total := r.neInfoRepository.SelectByPage(query)

	// 网元直连读取网元服务状态
	if bandStatus {
		r.bandNeStatus(&rows)
	}

	return rows, total
}

// Find 查询列表
//
// bandStatus 带状态信息
// bandHost 带主机信息
func (r NeInfo) Find(ne model.NeInfo, bandStatus bool, bandHost bool) []model.NeInfo {
	list := r.neInfoRepository.SelectList(ne)

	// 网元直连读取网元服务状态
	if bandStatus {
		r.bandNeStatus(&list)
	}

	// 网元主机信息
	if bandHost {
		r.bandNeHosts(&list)
	}

	return list
}

// bandNeStatus 网元列表项数据带网元服务状态
func (r NeInfo) bandNeStatus(arr *[]model.NeInfo) {
	for i := range *arr {
		v := (*arr)[i]
		result, err := neFetchlink.NeState(v)
		if err != nil {
			(*arr)[i].ServerState = map[string]any{
				"online": false,
			}
			// 网元状态设置为离线
			if v.Status != 0 {
				v.Status = 0
				(*arr)[i].Status = v.Status
				(*arr)[i].UpdateTime = time.Now().UnixMilli()
				r.neInfoRepository.UpdateState(v.ID, v.Status)
			}
			continue
		}
		result["online"] = true
		(*arr)[i].ServerState = result
		// 网元状态设置为在线
		var status int64 = 1
		if parse.Boolean(result["standby"]) {
			status = 3
		}
		// 下发网管配置信息给网元
		if _, err = neFetchlink.NeConfigOMC(v); err != nil {
			status = 2
		}
		(*arr)[i].Status = status
		if v.Status != status {
			(*arr)[i].UpdateTime = time.Now().UnixMilli()
			r.neInfoRepository.UpdateState(v.ID, status)
		}
	}
}

// bandNeHosts 网元列表项数据带网元主机信息
func (r NeInfo) bandNeHosts(arr *[]model.NeInfo) {
	for i := range *arr {
		v := (*arr)[i]
		if v.HostIDs != "" {
			hostIds := strings.Split(v.HostIDs, ",")
			if len(hostIds) <= 1 {
				continue
			}
			for _, v := range hostIds {
				hostId := parse.Number(v)
				neHost := r.neHostService.FindById(hostId)
				if neHost.ID == 0 || neHost.ID != hostId {
					continue
				}
				(*arr)[i].Hosts = append((*arr)[i].Hosts, neHost)
			}
		}
	}
}

// FindById 通过ID查询
//
// bandHost 带主机信息
func (r NeInfo) FindById(id int64, bandHost bool) model.NeInfo {
	if id <= 0 {
		return model.NeInfo{}
	}
	neInfos := r.neInfoRepository.SelectByIds([]int64{id})
	if len(neInfos) > 0 {
		// 带主机信息
		if neInfos[0].HostIDs != "" && bandHost {
			r.bandNeHosts(&neInfos)
		}
		return neInfos[0]
	}
	return model.NeInfo{}
}

// Insert 新增信息
func (r NeInfo) Insert(neInfo model.NeInfo) int64 {
	// 主机信息新增
	if neInfo.Hosts != nil {
		uuid := generate.Code(4)
		var hostIDs []string
		for _, host := range neInfo.Hosts {
			host.Title = fmt.Sprintf("%s_%d_%s", neInfo.NeName, host.Port, uuid)
			host.GroupID = "1"
			host.CreateBy = neInfo.CreateBy
			hostId := r.neHostService.Insert(host)
			if hostId > 0 {
				hostIDs = append(hostIDs, fmt.Sprint(hostId))
			}
		}
		neInfo.HostIDs = strings.Join(hostIDs, ",")
	}

	insertId := r.neInfoRepository.Insert(neInfo)
	if insertId > 0 {
		// 刷新缓存
		r.RefreshByNeTypeAndNeID(neInfo.NeType, neInfo.NeId)
	}
	return insertId
}

// Update 修改信息
func (r NeInfo) Update(neInfo model.NeInfo) int64 {
	// 主机信息更新
	if neInfo.Hosts != nil {
		uuid := generate.Code(4)
		for _, host := range neInfo.Hosts {
			if host.ID != 0 {
				host.Title = fmt.Sprintf("%s_%d_%s", neInfo.NeName, host.Port, uuid)
				host.GroupID = "1"
				host.UpdateBy = neInfo.UpdateBy
				r.neHostService.Update(host)
			}
		}
	}

	num := r.neInfoRepository.Update(neInfo)
	if num > 0 {
		// 刷新缓存
		r.RefreshByNeTypeAndNeID(neInfo.NeType, neInfo.NeId)
	}
	return num
}

// DeleteByIds 批量删除信息
func (r NeInfo) DeleteByIds(ids []int64) (int64, error) {
	// 检查是否存在
	infos := r.neInfoRepository.SelectByIds(ids)
	if len(infos) <= 0 {
		return 0, fmt.Errorf("neHostCmd.noData")
	}

	if len(infos) == len(ids) {
		for _, v := range infos {
			// 主机信息删除
			if v.HostIDs != "" {
				hostIds := make([]int64, 0)
				arr := strings.Split(v.HostIDs, ",")
				for _, hostId := range arr {
					hostIds = append(hostIds, parse.Number(hostId))
				}
				r.neHostService.DeleteByIds(hostIds, false)
			}
			// 删除License
			neLicense := NewNeLicense.FindByNeTypeAndNeID(v.NeType, v.NeId)
			if neLicense.NeId == v.NeId {
				NewNeLicense.DeleteByIds([]int64{neLicense.ID})
			}
			// 删除Version
			neVersion := NewNeVersion.FindByNeTypeAndNeID(v.NeType, v.NeId)
			if neVersion.NeId == v.NeId {
				NewNeVersion.DeleteByIds([]int64{neVersion.ID})
			}
			// 缓存信息删除
			redis.Del("", fmt.Sprintf("%s:%s:%s", constants.CACHE_NE_INFO, v.NeType, v.NeId))
		}
		rows := r.neInfoRepository.DeleteByIds(ids)
		return rows, nil
	}
	// 删除信息失败！
	return 0, fmt.Errorf("delete fail")
}

// CheckUniqueNeTypeAndNeId 校验同类型下标识是否唯一
func (r NeInfo) CheckUniqueNeTypeAndNeId(neType, neId string, id int64) bool {
	uniqueId := r.neInfoRepository.CheckUniqueNeTypeAndNeId(model.NeInfo{
		NeType: neType,
		NeId:   neId,
	})
	if uniqueId == id {
		return true
	}
	return uniqueId == 0
}

// NeRunSSHClient 网元主机的SSH客户端-为创建相关连接，注意结束后 Close()
func (r NeInfo) NeRunSSHClient(neType, neId string) (*ssh.ConnSSH, error) {
	neInfo := r.FindByNeTypeAndNeID(neType, neId)
	if neInfo.NeId != neId {
		logger.Errorf("NeRunSSHClient NeType:%s NeID:%s not found", neType, neId)
		return nil, fmt.Errorf("neinfo not found")
	}
	// 取主机信息
	if neInfo.HostIDs == "" {
		logger.Errorf("NeRunSSHClient NeType:%s NeID:%s hostId not found", neType, neId)
		return nil, fmt.Errorf("neinfo hostId not found")
	}
	hostIds := strings.Split(neInfo.HostIDs, ",")
	if len(hostIds) <= 1 {
		logger.Errorf("NeRunTelnetClient hosts id %s not found", neInfo.HostIDs)
		return nil, fmt.Errorf("neinfo host id not found")
	}
	hostId := parse.Number(hostIds[0]) // 网元主机ssh 0：22
	neHost := r.neHostService.FindById(hostId)
	if neHost.ID == 0 || neHost.ID != hostId {
		logger.Errorf("NeRunTelnetClient Hosts %s not found", neInfo.HostIDs)
		return nil, fmt.Errorf("neinfo host not found")
	}
	if neHost.HostType != "ssh" {
		logger.Errorf("NeRunSSHClient Hosts first HostType %s not ssh", neHost.HostType)
		return nil, fmt.Errorf("neinfo host type not ssh")
	}

	var connSSH ssh.ConnSSH
	neHost.CopyTo(&connSSH)
	var client *ssh.ConnSSH
	var err error
	if neHost.AuthMode == "2" {
		client, err = connSSH.NewClientByLocalPrivate()
	} else {
		client, err = connSSH.NewClient()
	}
	if err != nil {
		logger.Errorf("NeRunSSHClient NewClient err => %s", err.Error())
		return nil, fmt.Errorf("neinfo ssh client new err")
	}
	return client, nil
}

// NeRunSSHCmd 网元主机的SSH客户端发送cmd命令
func (r NeInfo) NeRunSSHCmd(neType, neId, cmdStr string) (string, error) {
	// sshClient, err := r.NeRunSSHClient(neType, neId)
	// if err != nil {
	// 	return "", err
	// }
	// defer sshClient.Close()

	// // 执行命令
	// output, err := sshClient.RunCMD(cmd)
	output, err := cmd.Exec(cmdStr)
	if err != nil {
		logger.Errorf("NeRunSSHCmd RunCMD %s err => %s", output, err.Error())
		return "", fmt.Errorf("neinfo ssh run cmd err")
	}
	return output, nil
}

// NeRunTelnetClient 网元主机的Telnet客户端-为创建相关连接，注意结束后 Close()
// num 是网元主机telnet 1：4100 2：5200（UPF标准版）
func (r NeInfo) NeRunTelnetClient(neType, neId string, num int) (*telnet.ConnTelnet, error) {
	neInfo := r.FindByNeTypeAndNeID(neType, neId)
	if neInfo.NeId != neId {
		logger.Errorf("NeRunTelnetClient NeType:%s NeID:%s not found", neType, neId)
		return nil, fmt.Errorf("neinfo not found")
	}
	// 取主机信息
	if neInfo.HostIDs == "" {
		logger.Errorf("NeRunTelnetClient NeType:%s NeID:%s hostId not found", neType, neId)
		return nil, fmt.Errorf("neinfo hostId not found")
	}
	hostIds := strings.Split(neInfo.HostIDs, ",")
	if len(hostIds) <= 1 {
		logger.Errorf("NeRunTelnetClient hosts id %s not found", neInfo.HostIDs)
		return nil, fmt.Errorf("neinfo host id not found")
	}
	hostId := parse.Number(hostIds[num]) // 网元主机telnet 1：4100 2：5200
	neHost := r.neHostService.FindById(hostId)
	if neHost.ID == 0 || neHost.ID != hostId {
		logger.Errorf("NeRunTelnetClient Hosts %s not found", neInfo.HostIDs)
		return nil, fmt.Errorf("neinfo host not found")
	}

	// 创建链接Telnet客户端
	var connTelnet telnet.ConnTelnet
	neHost.CopyTo(&connTelnet)
	telnetClient, err := connTelnet.NewClient()
	if err != nil {
		logger.Errorf("NeRunTelnetClient NewClient err => %s", err.Error())
		return nil, fmt.Errorf("neinfo telnet client new err")
	}
	return telnetClient, nil
}

// NeRunRedisClient 网元主机的Redis客户端-为创建相关连接，注意结束后 Close()
// 暂时只有UDM有Redis配置项
func (r NeInfo) NeRunRedisClient(neType, neId string) (*redis.ConnRedis, error) {
	neInfo := r.FindByNeTypeAndNeID(neType, neId)
	if neInfo.NeId != neId {
		logger.Errorf("NeRunRedisClient NeType:%s NeID:%s not found", neType, neId)
		return nil, fmt.Errorf("neinfo not found")
	}
	// 取主机信息
	if neInfo.HostIDs == "" {
		logger.Errorf("NeRunRedisClient NeType:%s NeID:%s hostId not found", neType, neId)
		return nil, fmt.Errorf("neinfo hostId not found")
	}
	hostIds := strings.Split(neInfo.HostIDs, ",")
	if len(hostIds) <= 2 {
		logger.Errorf("NeRunRedisClient hosts id %s not found", neInfo.HostIDs)
		return nil, fmt.Errorf("neinfo host id not found")
	}
	hostId := parse.Number(hostIds[2])
	neHost := r.neHostService.FindById(hostId)
	if neHost.ID == 0 || neHost.ID != hostId {
		logger.Errorf("NeRunRedisClient Hosts %s not found", neInfo.HostIDs)
		return nil, fmt.Errorf("neinfo host not found")
	}

	// 创建链接Redis客户端
	var connRedis redis.ConnRedis
	neHost.CopyTo(&connRedis)
	redisClient, err := connRedis.NewClient()
	if err != nil {
		logger.Errorf("NeRunRedisClient NewClient err => %s", err.Error())
		return nil, fmt.Errorf("neinfo redis client new err")
	}
	return redisClient, nil
}

// NeConfOAMReadSync 网元OAM配置文件读取
func (r NeInfo) NeConfOAMReadSync(neType, neId string) (map[string]any, error) {
	oamData, err := r.neConfOAMRead(neType, neId, true)
	if err != nil {
		return nil, err
	}

	// UPF和SMF 全小写的key
	// 网元HTTP服务
	if v, ok := oamData["httpmanagecfg"]; ok && v != nil {
		item := v.(map[string]any)
		if v, ok := item["iptype"]; ok && v != nil {
			item["ipType"] = v
			delete(item, "iptype")
		}
		oamData["httpManageCfg"] = item
		delete(oamData, "httpmanagecfg")
		r.neConfOAMWirte(neType, neId, oamData, false)
	}
	// 对网管HTTP配置
	if v, ok := oamData["oamconfig"]; ok && v != nil {
		item := v.(map[string]any)
		if v, ok := item["iptype"]; ok && v != nil {
			item["ipType"] = v
			delete(item, "iptype")
		}
		if v, ok := item["neconfig"]; ok && v != nil {
			item["neConfig"] = v
			delete(item, "neconfig")
		}
		oamData["oamConfig"] = item
		delete(oamData, "oamconfig")
		r.neConfOAMWirte(neType, neId, oamData, false)
	}
	// 对网管SNMP配置
	if v, ok := oamData["snmpconfig"]; ok && v != nil {
		item := v.(map[string]any)
		if v, ok := item["iptype"]; ok && v != nil {
			item["ipType"] = v
			delete(item, "iptype")
		}
		oamData["snmpConfig"] = item
		delete(oamData, "snmpconfig")
		r.neConfOAMWirte(neType, neId, oamData, false)
	}
	// 对网管KPI上报配置
	if v, ok := oamData["kpiconfig"]; ok && v != nil {
		item := v.(map[string]any)
		oamData["kpiConfig"] = item
		delete(oamData, "kpiconfig")
		r.neConfOAMWirte(neType, neId, oamData, false)
	}

	// NSSF和MME 配置KPIconfig名不一致时
	if v, ok := oamData["KPIconfig"]; ok && v != nil {
		item := v.(map[string]any)
		oamData["kpiConfig"] = item
		delete(oamData, "KPIconfig")
		r.neConfOAMWirte(neType, neId, oamData, false)
	}

	return oamData, nil
}

// neConfOAMData 网元OAM配置文件默认格式数据
func (r NeInfo) neConfOAMData() map[string]any {
	return map[string]any{
		"httpManageCfg": map[string]any{
			"ipType": "ipv4",
			"ipv4":   "172.16.5.1", // 必改
			"ipv6":   "",
			"port":   33030,
			"scheme": "http",
		},
		"oamConfig": map[string]any{
			"enable": true,
			"ipType": "ipv4",
			"ipv4":   "172.16.5.100", // 必改
			"ipv6":   "",
			"port":   33030,
			"scheme": "http",
			// 必改
			"neConfig": map[string]any{
				"neId":       "001",
				"rmUid":      "4400HX1XXX001",
				"neName":     "XXX_001",
				"dn":         "-",
				"vendorName": "GD",
				"province":   "-",
				"pvFlag":     "PNF",
			},
		},
		"snmpConfig": map[string]any{
			"enable": false,
			"ipType": "ipv4",
			"ipv4":   "172.16.5.1", // 必改
			"ipv6":   "",
			"port":   4957,
		},
		"kpiConfig": map[string]any{
			"enable": true,
			"timer":  60, // 必改
		},
		// "pubConfigPath": "/usr/local/etc/conf/para5G.yaml", // 网元只会读一次后续会置空，建议不放
	}
}

// neConfOAMRead 网元OAM配置文件读取 sync从网元端同步到本地
func (r NeInfo) neConfOAMRead(neType, neId string, sync bool) (map[string]any, error) {
	neTypeLower := strings.ToLower(neType)
	fileName := "oam_manager.yaml"
	// 网管本地路径
	localFilePath := fmt.Sprintf("/usr/local/omc/backup/ne_config/%s/%s/%s", neTypeLower, neId, fileName)
	if runtime.GOOS == "windows" {
		localFilePath = fmt.Sprintf("C:%s", localFilePath)
	}

	// 从网元端同步到本地
	if sync {
		// // 网元主机的SSH客户端
		// sshClient, err := r.NeRunSSHClient(neType, neId)
		// if err != nil {
		// 	return nil, fmt.Errorf("ne info ssh client err")
		// }
		// defer sshClient.Close()
		// // 网元主机的SSH客户端进行文件传输
		// sftpClient, err := sshClient.NewClientSFTP()
		// if err != nil {
		// 	return nil, fmt.Errorf("ne info sftp client err")
		// }
		// defer sftpClient.Close()
		// 网元端文件路径
		neFilePath := fmt.Sprintf("/usr/local/etc/%s/%s", neTypeLower, fileName)
		// 修改网元文件权限
		// sshClient.RunCMD(fmt.Sprintf("sudo touch %s && sudo chmod o+rw %s", neFilePath, neFilePath))
		cmd.Execf("sudo touch %s && sudo chmod o+rw %s", neFilePath, neFilePath)
		// 网元端复制到本地
		// if err = sftpClient.CopyFileRemoteToLocal(neFilePath, localFilePath); err != nil {
		// 	return nil, fmt.Errorf("copy oam config err")
		// }
		if err := file.CopyFile(neFilePath, localFilePath); err != nil {
			return nil, fmt.Errorf("copy oam config err")
		}
	}

	// 读取文件内容
	bytes, err := os.ReadFile(localFilePath)
	if err != nil || len(bytes) == 0 {
		// logger.Warnf("NeConfOAMRead ReadFile => %s", err.Error())
		// return nil, fmt.Errorf("read file error")
		// 无保留文件时返回默认文件数据
		oamData := r.neConfOAMData()
		r.neConfOAMWirte(neType, neId, oamData, false)
		return oamData, nil
	}
	content := string(bytes)

	// 序列化Map
	mapData, err := parse.ConvertConfigToMap("yaml", content)
	if err != nil {
		logger.Warnf("NeConfOAMRead ConvertConfigToMap => %s", err.Error())
		return nil, fmt.Errorf("content convert type error")
	}
	return mapData, nil
}

// neConfOAMWirte 网元OAM配置文件写入 content内容 sync同步到网元端
func (r NeInfo) neConfOAMWirte(neType, neId string, content any, sync bool) error {
	neTypeLower := strings.ToLower(neType)
	fileName := "oam_manager.yaml"
	// 网管本地路径
	omcPath := "/usr/local/omc/backup/ne_config"
	if runtime.GOOS == "windows" {
		omcPath = fmt.Sprintf("C:%s", omcPath)
	}
	localFilePath := fmt.Sprintf("%s/%s/%s/%s", omcPath, neTypeLower, neId, fileName)

	// 写入文件
	if err := parse.ConvertConfigToFile("yaml", localFilePath, content); err != nil {
		return fmt.Errorf("please check if the file exists or write permissions")
	}

	// 同步到网元端
	if sync {
		// // 网元主机的SSH客户端
		// sshClient, err := r.NeRunSSHClient(neType, neId)
		// if err != nil {
		// 	return err
		// }
		// defer sshClient.Close()
		// // 网元主机的SSH客户端进行文件传输
		// sftpClient, err := sshClient.NewClientSFTP()
		// if err != nil {
		// 	return err
		// }
		// defer sftpClient.Close()

		// 网元端配置路径
		neFilePath := fmt.Sprintf("/usr/local/etc/%s/%s", neTypeLower, fileName)
		neFileDir := filepath.ToSlash(filepath.Dir(neFilePath))
		// // 修改网元文件权限
		// sshClient.RunCMD(fmt.Sprintf("sudo mkdir -p %s && sudo chmod 775 %s && sudo touch %s && sudo chmod o+rw %s", neFileDir, neFileDir, neFilePath, neFilePath))
		cmd.Execf("sudo mkdir -p %s && sudo chmod 775 %s && sudo touch %s && sudo chmod o+rw %s", neFileDir, neFileDir, neFilePath, neFilePath)
		// // 复制到网元进行覆盖
		// if err = sftpClient.CopyFileLocalToRemote(localFilePath, neFilePath); err != nil {
		// 	return fmt.Errorf("please check if scp remote copy is allowed")
		// }
		if err := file.CopyFile(localFilePath, neFilePath); err != nil {
			return fmt.Errorf("please check if scp remote copy is allowed")
		}
	}

	return nil
}

// NeConfOAMWirteSync 网元OAM配置文件生成并同步
func (r NeInfo) NeConfOAMWirteSync(neInfo model.NeInfo, content map[string]any, sync bool) error {
	oamData, err := r.neConfOAMRead(neInfo.NeType, neInfo.NeId, false)
	if oamData == nil || err != nil {
		return fmt.Errorf("error read OAM file info")
	}
	// 网元HTTP服务
	httpManageCfg, ok := oamData["httpManageCfg"].(map[string]any)
	if !ok {
		neConfOAMData := r.neConfOAMData()
		httpManageCfg = neConfOAMData["httpManageCfg"].(map[string]any)
	}
	httpManageCfg["port"] = neInfo.Port
	if strings.Contains(neInfo.IP, ":") {
		httpManageCfg["ipType"] = "ipv6"
		httpManageCfg["ipv6"] = neInfo.IP
	}
	if strings.Contains(neInfo.IP, ".") {
		httpManageCfg["ipType"] = "ipv4"
		httpManageCfg["ipv4"] = neInfo.IP
	}
	delete(httpManageCfg, "iptype")
	delete(oamData, "httpmanagecfg")
	oamData["httpManageCfg"] = httpManageCfg

	// 对网管HTTP配置
	oamConfig, ok := oamData["oamConfig"].(map[string]any)
	if !ok {
		neConfOAMData := r.neConfOAMData()
		oamConfig = neConfOAMData["oamConfig"].(map[string]any)
	}
	delete(oamConfig, "neconfig")
	oamConfig["neConfig"] = map[string]string{
		"neId":       neInfo.NeId,
		"rmUid":      neInfo.RmUID,
		"neName":     neInfo.NeName,
		"dn":         neInfo.Dn,
		"vendorName": neInfo.VendorName,
		"province":   neInfo.Province,
		"pvFlag":     neInfo.PvFlag,
	}
	// 公共参数指定的OMC
	if omcIP, ok := r.Para5GData["OMC_IP"]; ok && omcIP != "" {
		if strings.Contains(omcIP, ":") {
			oamConfig["ipType"] = "ipv6"
			oamConfig["ipv6"] = omcIP
		}
		if strings.Contains(omcIP, ".") {
			oamConfig["ipType"] = "ipv4"
			oamConfig["ipv4"] = omcIP
		}
	}
	// 传入的变更
	if v, ok := content["omcIP"]; ok && v != "" && v != nil {
		omcIP := v.(string)
		if strings.Contains(omcIP, ":") {
			oamConfig["ipType"] = "ipv6"
			oamConfig["ipv6"] = omcIP
		}
		if strings.Contains(omcIP, ".") {
			oamConfig["ipType"] = "ipv4"
			oamConfig["ipv4"] = omcIP
		}
	}
	delete(oamConfig, "iptype")
	if oamEnable, ok := content["oamEnable"]; ok && oamEnable != nil {
		oamConfig["enable"] = parse.Boolean(oamEnable)
	}
	if oamPort, ok := content["oamPort"]; ok && oamPort != nil {
		oamConfig["port"] = parse.Number(oamPort)
	}
	delete(oamData, "oamconfig")
	oamData["oamConfig"] = oamConfig

	// 对网管SNMP配置
	snmpConfig, ok := oamData["snmpConfig"].(map[string]any)
	if !ok {
		neConfOAMData := r.neConfOAMData()
		snmpConfig = neConfOAMData["snmpConfig"].(map[string]any)
	}
	if strings.Contains(neInfo.IP, ":") {
		snmpConfig["ipType"] = "ipv6"
		snmpConfig["ipv6"] = neInfo.IP
	}
	if strings.Contains(neInfo.IP, ".") {
		snmpConfig["ipType"] = "ipv4"
		snmpConfig["ipv4"] = neInfo.IP
	}
	delete(snmpConfig, "iptype")
	if snmpEnable, ok := content["snmpEnable"]; ok && snmpEnable != nil {
		snmpConfig["enable"] = parse.Boolean(snmpEnable)
	}
	if snmpPort, ok := content["snmpPort"]; ok && snmpPort != nil {
		snmpConfig["port"] = parse.Number(snmpPort)
	}
	delete(oamData, "snmpconfig")
	oamData["snmpConfig"] = snmpConfig

	// 对网管KPI上报配置
	kpiConfig, ok := oamData["kpiConfig"].(map[string]any)
	if !ok {
		neConfOAMData := r.neConfOAMData()
		kpiConfig = neConfOAMData["kpiConfig"].(map[string]any)
	}
	if neInfo.NeType == "UPF" {
		kpiConfig["timer"] = 5
	} else {
		kpiConfig["timer"] = 60
	}
	if kpiEnable, ok := content["kpiEnable"]; ok && kpiEnable != nil {
		kpiConfig["enable"] = parse.Boolean(kpiEnable)
	}
	if kpiTimer, ok := content["kpiTimer"]; ok && kpiTimer != nil {
		kpiConfig["timer"] = parse.Number(kpiTimer)
	}
	delete(oamData, "kpiconfig")
	oamData["kpiConfig"] = kpiConfig

	if err := r.neConfOAMWirte(neInfo.NeType, neInfo.NeId, oamData, sync); err != nil {
		return fmt.Errorf("error wirte OAM file info")
	}
	return nil
}

// NeConfPara5GRead 网元公共配置文件读取
func (r NeInfo) NeConfPara5GRead() (map[string]any, error) {
	// 网管本地路径
	omcFilePath := "/usr/local/etc/omc/para5G.yaml"
	if runtime.GOOS == "windows" {
		omcFilePath = fmt.Sprintf("C:%s", omcFilePath)
	}
	// 读取文件内容
	bytes, err := os.ReadFile(omcFilePath)
	if err != nil {
		logger.Warnf("NeConfPara5GRead ReadFile => %s", err.Error())
		return nil, fmt.Errorf("read file error")
	}
	content := string(bytes)

	// 序列化Map
	mapData, err := parse.ConvertConfigToMap("yaml", content)
	if err != nil {
		logger.Warnf("NeConfPara5GRead ConvertConfigToMap => %s", err.Error())
		return nil, fmt.Errorf("content convert type error")
	}
	return mapData, nil
}

// NeConfPara5GWirte 网元公共配置文件写入 content内容 syncNE同步到网元端NeType@NeId
func (r *NeInfo) NeConfPara5GWirte(content map[string]any, syncNE []string) error {
	// 网管本地路径
	omcFilePath := "/usr/local/etc/omc/para5G.yaml"
	if runtime.GOOS == "windows" {
		omcFilePath = fmt.Sprintf("C:%s", omcFilePath)
	}

	if err := parse.ConvertConfigToFile("yaml", omcFilePath, content); err != nil {
		return fmt.Errorf("please check if the file exists or write permissions")
	}

	// 同步到网元端
	if len(syncNE) > 0 {
		errMsg := []string{}
		for _, neTI := range syncNE {
			ti := strings.SplitN(neTI, "@", 2)
			// // 网元主机的SSH客户端
			// sshClient, err := r.NeRunSSHClient(ti[0], ti[1])
			// if err != nil {
			// 	errMsg = append(errMsg, fmt.Sprintf("%s : %s", ti, err.Error()))
			// 	continue
			// }
			// defer sshClient.Close()
			// // 网元主机的SSH客户端进行文件传输
			// sftpClient, err := sshClient.NewClientSFTP()
			// if err != nil {
			// 	errMsg = append(errMsg, fmt.Sprintf("%s : %s", ti, err.Error()))
			// 	continue
			// }
			// defer sftpClient.Close()

			// 网元端配置路径
			neFilePath := "/usr/local/etc/conf/para5G.yaml"
			neFileDir := filepath.ToSlash(filepath.Dir(neFilePath))
			// 修改网元文件权限
			// sshClient.RunCMD(fmt.Sprintf("sudo mkdir -p %s && sudo chmod 775 %s && sudo touch %s && sudo chmod o+rw %s", neFileDir, neFileDir, neFilePath, neFilePath))
			cmd.Execf("sudo mkdir -p %s && sudo chmod 775 %s && sudo touch %s && sudo chmod o+rw %s", neFileDir, neFileDir, neFilePath, neFilePath)
			// 复制到网元进行覆盖
			// if err = sftpClient.CopyFileLocalToRemote(omcFilePath, neFilePath); err != nil {
			// 	errMsg = append(errMsg, fmt.Sprintf("%s : please check if scp remote copy is allowed", ti))
			// 	continue
			// }
			if err := file.CopyFile(omcFilePath, neFilePath); err != nil {
				errMsg = append(errMsg, fmt.Sprintf("%s : please check if scp remote copy is allowed", ti))
				continue
			}
		}
		if len(errMsg) > 0 {
			return fmt.Errorf("%s", strings.Join(errMsg, "\r\n"))
		}
	}

	// 转换一份数据到全局
	r.Para5GData = r.neConfPara5GDataConvert(content)
	return nil
}

// NeConfPara5GConvert 网元公共配置数据转化 content网元公共配置文件读取内容
func (r NeInfo) neConfPara5GDataConvert(content map[string]any) map[string]string {
	defer func() {
		if err := recover(); err != nil {
			logger.Errorf("NeConfPara5GDataConvert panic: %v", err)
			// 文件异常就删除配置
			omcFilePath := "/usr/local/etc/omc/para5G.yaml"
			if runtime.GOOS == "windows" {
				omcFilePath = fmt.Sprintf("C:%s", omcFilePath)
			}
			os.Remove(omcFilePath)
		}
	}()

	basic := content["basic"].(map[string]any)
	external := content["external"].(map[string]any)
	sbi := content["sbi"].(map[string]any)

	mcc := "460"
	mnc := "01"
	mncDomain := "001"
	if plmnId, plmnIdOk := basic["plmnId"].(map[string]any); plmnIdOk {
		mcc = plmnId["mcc"].(string)
		mnc = plmnId["mnc"].(string)
		// If a user input two digit MNC, add a leading zero
		if len(mnc) == 2 {
			mncDomain = fmt.Sprintf("0%s", mnc)
		} else {
			mncDomain = mnc
		}
	}

	sst := "1"
	sd := "000001"
	if plmnId, plmnIdOk := basic["snssai"].(map[string]any); plmnIdOk {
		sst = plmnId["sst"].(string)
		sd = plmnId["sd"].(string)
	}

	n3IPAmdMask := external["upfn3_ip"].(string)
	n3Arr := strings.SplitN(n3IPAmdMask, "/", 2)
	n3IP := n3Arr[0]
	n3Mask := "255.255.255.0"
	if len(n3Arr) > 1 {
		n3Mask = parse.ConvertIPMask(parse.Number(n3Arr[1]))
	}

	n6IPAmdMask := external["upfn6_ip"].(string)
	n6Arr := strings.SplitN(n6IPAmdMask, "/", 2)
	n6IP := n6Arr[0]
	n6Mask := "255.255.255.0"
	if len(n6Arr) > 1 {
		n6Mask = parse.ConvertIPMask(parse.Number(n6Arr[1]))
	}

	ueIPAmdMask := external["ue_pool"].(string)
	ueArr := strings.SplitN(ueIPAmdMask, "/", 2)
	ueIP := ueArr[0]
	ueCicr := "24"
	ueMask := "255.255.255.0"
	if len(ueArr) > 1 {
		ueCicr = ueArr[1]
		ueMask = parse.ConvertIPMask(parse.Number(ueArr[1]))
	}

	return map[string]string{
		// basic
		"TAC":        basic["tac"].(string),
		"MCC":        mcc,
		"MNC":        mnc,
		"MNC_DOMAIN": mncDomain,
		"SST":        sst,
		"SD":         sd,
		"DNN_DATA":   basic["dnn_data"].(string),
		"DNN_IMS":    basic["dnn_ims"].(string),

		// external
		"N2_IP":           external["amfn2_ip"].(string),
		"UE_POOL":         external["ue_pool"].(string), // 轻量版才用配置
		"UE_IP":           ueIP,
		"UE_MASK":         ueMask,
		"UE_CIDR":         ueCicr,
		"UPF_TYPE":        external["upf_type"].(string),        // 类型 StandardUPF LightUPF
		"UPF_DRIVER_TYPE": external["upf_driver_type"].(string), // 网卡驱动 vmxnet3 host dpdk
		"N3_IP":           n3IP,
		"N3_MASK":         n3Mask,
		"N3_GW":           external["upfn3_gw"].(string),
		"N3_PCI":          external["upfn3_pci"].(string),
		"N3_MAC":          external["upfn3_mac"].(string),
		"N3_NIC_NAME":     external["upfn3_card_name"].(string), // 网卡名 eth0
		"N6_IP":           n6IP,
		"N6_MASK":         n6Mask,
		"N6_GW":           external["upfn6_gw"].(string),
		"N6_PCI":          external["upfn6_pci"].(string),
		"N6_MAC":          external["upfn6_mac"].(string),
		"N6_NIC_NAME":     external["upfn6_card_name"].(string), // 网卡名 eth0

		"SIP_IP": external["ims_sip_ip"].(string),

		"S1_MMEIP":  external["mmes1_ip"].(string),
		"S11_MMEIP": external["mmes11_ip"].(string),
		"S10_MMEIP": external["mmes10_ip"].(string),

		// sbi
		"OMC_IP":   sbi["omc_ip"].(string),
		"IMS_IP":   sbi["ims_ip"].(string),
		"AMF_IP":   sbi["amf_ip"].(string),
		"AUSF_IP":  sbi["ausf_ip"].(string),
		"UDM_IP":   sbi["udm_ip"].(string),
		"SMF_IP":   sbi["smf_ip"].(string),
		"PCF_IP":   sbi["pcf_ip"].(string),
		"NSSF_IP":  sbi["nssf_ip"].(string),
		"NRF_IP":   sbi["nrf_ip"].(string),
		"UPF_IP":   sbi["upf_ip"].(string),
		"LMF_IP":   sbi["lmf_ip"].(string),
		"NEF_IP":   sbi["nef_ip"].(string),
		"MME_IP":   sbi["mme_ip"].(string),
		"N3IWF_IP": sbi["n3iwf_ip"].(string),
		"SMSC_IP":  sbi["smsc_ip"].(string),

		"DB_IP": sbi["db_ip"].(string),
	}
}
