package main

import (
	"encoding/xml"
	"fmt"
	"os"
	"regexp"
	"strconv"
	"strings"
	"time"

	pmschema "ems.agt/crontask/pm/schema"
	"ems.agt/lib/global"
	"ems.agt/lib/log"

	"gopkg.in/yaml.v3"
)

var (
	neTypes = []string{"AMF", "SMF", "UDM", "UPF", "AUSF"}
)

func (t *TaskFunc) GenPmXmlFile(uri, params, body string) {
	for _, neType := range neTypes {
		log.Debugf("GenPmXmlFile process %s xml file", neType)
		t.GenNFPMXmlFile(neType)
	}
}

func (t *TaskFunc) ReadPmYaml(cmfile string) (map[string]interface{}, error) {
	log.Debug("cmfile:", cmfile)
	file, err := os.ReadFile(cmfile)
	if err != nil {
		log.Error(err)
		return nil, err
	}
	log.Debug("file:", file)
	resultMap := make(map[string]interface{})
	err = yaml.Unmarshal(file, resultMap)
	if err != nil {
		log.Error(err)
		return nil, err
	}

	log.Debug("resultMap:", resultMap)
	return resultMap, nil
}

func (t *TaskFunc) IsPseudoSubPmName(pmName string) bool {
	return strings.Contains(pmName, "._")
}

func (t *TaskFunc) GenNFPMXmlFile(neType string) error {
	log.Info("GenNFPMXmlFile processing...")

	var nes []NeInfo
	_, err := XormGetNeInfoByType(neType, &nes)
	if err != nil {
		log.Error("Failed to get all ne info:", err)
		return err
	}

	ti := time.Now()
	var startTime string
	timestamp := ti.Format("2006-01-02 15:04:05")

	index := global.GetCurrentTimeSliceIndexByPeriod(ti, 15)
	date := ti.Format("2006-01-02")
	dateHour := ti.Format("2006010215")
	log.Debugf("date: %s index:%d dateHour:%s", date, index, dateHour)

	_, offset := ti.Zone()
	var tzOffset string
	if offset >= 0 {
		tzOffset = "UTC+" + strconv.Itoa(offset/3600)
	} else {
		tzOffset = "UTC" + strconv.Itoa(offset/3600)
	}

	pmFile := new(pmschema.PmFile)

	var pmResults []NorthboundPm
	_, err = XormGetNorthboundPm(date, index, neType, &pmResults)
	if err != nil {
		log.Error("Failed to get northbound_pm:", err)
		return err
	}

	if len(pmResults) == 0 {
		log.Errorf("%s:%v", neType, global.ErrPMNotFoundData)
		return global.ErrPMNotFoundData
	}

	pmFile.XsAttr = "http://www.w3.org/2001/XMLSchema"
	pmFile.XsiAttr = "http://www.w3.org/2001/XMLSchema-instance"

	//创建目录
	path := fmt.Sprintf("%s/HX/%s/%s/PM/%s", yamlConfig.OMC.Province, yamlConfig.OMC.Vendor, yamlConfig.OMC.Name, dateHour)
	folderPath := global.CreateDir(path, yamlConfig.NBI.PM.XmlFileDir)

	var objectType string
	var measurement pmschema.Measurements
	for _, pmResult := range pmResults {
		for _, pmData := range pmResult.Datas {
			objectType = pmData.ObjectType
			measurement = pmschema.Measurements{ObjectType: objectType}
			measurement.PmData.Object.RmUIDAttr = pmResult.RmUID
			measurement.PmData.Object.DnAttr = pmResult.Dn
			measurement.PmData.Object.UserLabelAttr = pmResult.NeName
			startTime = pmResult.StartTime

			i := 1
			for _, pmKPI := range pmData.KPIs {
				measurement.PmName.N = append(measurement.PmName.N, pmschema.N{IAttr: i, Value: pmKPI.KPIID})
				cv := pmschema.CV{IAttr: i}
				isPseudo := true
				value := "0"
				reg := regexp.MustCompile(`_\w+`)
				//sns := strings.Split(pmData.KPIID, "_")
				for _, v := range pmKPI.KPIValues {
					if fmt.Sprintf("%v", v.Name) == "Total" {
						isPseudo = false
						value = fmt.Sprintf("%v", v.Value)
						break
					} else {
						isPseudo = true
						//if len(sns) > 1 {
						//	sns := strings.Split(sns[1], ".")
						//}
						sn := reg.ReplaceAllString(pmKPI.KPIID, v.Name)
						//sn := sns[0] + v.Name
						// cv.NV = append(cv.NV, pmschema.NV{SN: sn, SV: fmt.Sprintf("%v", v.Value)})
						cv.SN = append(cv.SN, sn)
						cv.SV = append(cv.SV, fmt.Sprintf("%v", v.Value))
					}
				}
				if isPseudo == false {
					measurement.PmData.Object.V = append(measurement.PmData.Object.V, pmschema.V{IAttr: i, Value: value})
				} else {
					measurement.PmData.Object.CV = append(measurement.PmData.Object.CV, cv)
				}

				i++
				//measurement.PmData.Object.V = append(measurement.PmData.Object.V, pmschema.V{IAttr: i, Value: sortValues[pmName].Value})
				//measurement.PmData.Object.CV = sortValues[pmName].Value
			}
			pmFile.Measurements = append(pmFile.Measurements, measurement)
			startTime = startTime[:len("2006-01-02 15:04:05")]

			pmFile.FileHeader = pmschema.FileHeader{
				TimeStamp:   timestamp,
				TimeZone:    tzOffset,
				Period:      15,
				VendorName:  yamlConfig.OMC.Vendor,
				ElementType: neType,
				PmVersion:   yamlConfig.NBI.PM.Version,
				StartTime:   startTime,
			}

			x, _ := xml.MarshalIndent(pmFile, "", "	")
			x = append([]byte(xml.Header), x...)

			//folderName := global.GetFmtTimeString(global.DateTime, startTime, global.DateHour)
			//folderPath := global.CreateDir(folderName, yamlConfig.NBI.PM.XmlFileDir)

			timefile := global.GetFmtTimeString(time.DateTime, startTime, global.DateData)

			xmlfile := fmt.Sprintf("%s/%s-PM-%s-%s-%s-%s-%s-15-001.xml",
				folderPath, yamlConfig.OMC.Province, neType, objectType, yamlConfig.OMC.HostNo, yamlConfig.NBI.PM.Version, timefile)
			tmpXmlfile := xmlfile + ".tmp"
			err = os.WriteFile(tmpXmlfile, x, 0664)
			if err != nil {
				log.Error("Failed to WriteFile xml file:", err)
				continue
			}
			err = os.Rename(tmpXmlfile, xmlfile)
			if err != nil {
				log.Error("Failed to Rename xml file:", err)
				continue
			}
			zipFile := xmlfile + ".zip"
			err = global.ZipOneFile(xmlfile, zipFile, false)
			if err != nil {
				log.Error("Failed to ZipOneFile:", err)
				continue
			}
			err = os.Remove(xmlfile)
			if err != nil {
				log.Error("Failed to delete file:", err)
				continue
			}
		}
	}

	return nil
}
