package backupEtcFromNE

import (
	"fmt"
	"os"
	"strings"
	"time"

	"nms_nbi/lib/dborm"
	"nms_nbi/lib/global"
	"nms_nbi/lib/log"
	"nms_nbi/restagent/config"
	"nms_nbi/src/framework/cron"
)

var NewProcessor = &BarProcessor{
	progress: 0,
	count:    0,
}

// bar 队列任务处理
type BarProcessor struct {
	// 任务进度
	progress int
	// 执行次数
	count int
}

type BarParams struct {
	Duration  int    `json:"duration"`
	TableName string `json:"tableName"`
	ColName   string `json:"colName"` // column name of time string
	Extras    string `json:"extras"`  // extras condition for where
}

func (s *BarProcessor) Execute(data any) (any, error) {
	log.Infof("execute %d，last progress： %d ", s.count, s.progress)
	s.count++

	options := data.(cron.JobData)
	sysJob := options.SysJob
	// var params BarParams

	// err := json.Unmarshal([]byte(sysJob.TargetParams), &params)
	// if err != nil {
	// 	return nil, err
	// }

	log.Infof("Repeat %v Job ID %s", options.Repeat, sysJob.JobID)

	var nes []dborm.NeInfo
	_, err := dborm.XormGetAllNeInfo(&nes)
	if err != nil {
		return nil, err
	}

	var successfulNEs, failureNEs []string
	for _, neInfo := range nes {
		neTypeUpper := strings.ToUpper(neInfo.NeType)
		neTypeLower := strings.ToLower(neInfo.NeType)
		nePath := fmt.Sprintf("%s/etc/%s", config.GetYamlConfig().OMC.Backup, neTypeLower)
		isExist, err := global.PathExists(nePath)
		if err != nil {
			log.Errorf("Failed to PathExists:", err)
			failureNEs = append(failureNEs, neInfo.NeType+"/"+neInfo.NeId)
			continue
		}
		if isExist {
			err = os.RemoveAll(nePath)
			if err != nil {
				log.Errorf("Failed to RemoveAll:", err)
				failureNEs = append(failureNEs, neInfo.NeType+"/"+neInfo.NeId)
				continue
			}
		}
		err = os.MkdirAll(nePath, os.ModePerm)
		if err != nil {
			log.Errorf("Failed to MkdirAll:", err)
			failureNEs = append(failureNEs, neInfo.NeType+"/"+neInfo.NeId)
			continue
		}

		var scpCmd string
		ipType := global.ParseIPAddr(neInfo.Ip)
		omcNetypeLower := strings.ToLower(config.GetYamlConfig().OMC.NeType)
		etcListIMS := "{*.yaml,mmtel,vars.cfg}"
		if config.GetYamlConfig().NE.EtcListIMS != "" {
			etcListIMS = config.GetYamlConfig().NE.EtcListIMS
		}
		switch neTypeLower {
		case omcNetypeLower:
			if ipType == global.IsIPv4 {
				scpCmd = fmt.Sprintf("scp -r %s@%s:%s/etc/*.yaml %s/etc/%s", config.GetYamlConfig().NE.User,
					neInfo.Ip, config.GetYamlConfig().NE.OmcDir, config.GetYamlConfig().OMC.Backup, neTypeLower)
			} else {
				scpCmd = fmt.Sprintf("scp -r %s@[%s]:%s/etc/*.yaml %s/etc/%s", config.GetYamlConfig().NE.User,
					neInfo.Ip, config.GetYamlConfig().NE.OmcDir, config.GetYamlConfig().OMC.Backup, neTypeLower)
			}

		case "ims":
			if ipType == global.IsIPv4 {
				scpCmd = fmt.Sprintf("scp -r %s@%s:%s/%s/%s %s/etc/%s", config.GetYamlConfig().NE.User,
					neInfo.Ip, config.GetYamlConfig().NE.EtcDir, neTypeLower,
					etcListIMS, config.GetYamlConfig().OMC.Backup, neTypeLower)
			} else {
				scpCmd = fmt.Sprintf("scp -r %s@[%s]:%s/%s/%s %s/etc/%s", config.GetYamlConfig().NE.User,
					neInfo.Ip, config.GetYamlConfig().NE.EtcDir, neTypeLower,
					etcListIMS, config.GetYamlConfig().OMC.Backup, neTypeLower)
			}

		case "mme":
			if ipType == global.IsIPv4 {
				scpCmd = fmt.Sprintf("scp -r %s@%s:%s/%s/*.conf %s/etc/%s", config.GetYamlConfig().NE.User,
					neInfo.Ip, config.GetYamlConfig().NE.EtcDir,
					neTypeLower, config.GetYamlConfig().OMC.Backup, neTypeLower)
			} else {
				scpCmd = fmt.Sprintf("scp -r %s@[%s]:%s/%s/*.conf %s/etc/%s", config.GetYamlConfig().NE.User,
					neInfo.Ip, config.GetYamlConfig().NE.EtcDir,
					neTypeLower, config.GetYamlConfig().OMC.Backup, neTypeLower)
			}

		default:
			if ipType == global.IsIPv4 {
				scpCmd = fmt.Sprintf("scp -r %s@%s:%s/%s/*.yaml %s/etc/%s", config.GetYamlConfig().NE.User,
					neInfo.Ip, config.GetYamlConfig().NE.EtcDir,
					neTypeLower, config.GetYamlConfig().OMC.Backup, neTypeLower)
			} else {
				scpCmd = fmt.Sprintf("scp -r %s@[%s]:%s/%s/*.yaml %s/etc/%s", config.GetYamlConfig().NE.User,
					neInfo.Ip, config.GetYamlConfig().NE.EtcDir,
					neTypeLower, config.GetYamlConfig().OMC.Backup, neTypeLower)
			}

		}

		zipFile := fmt.Sprintf("%s-%s-etc-%s.zip", neTypeLower, strings.ToLower(neInfo.NeId), time.Now().Format(global.DateData))
		zipFilePath := config.GetYamlConfig().OMC.Backup + "/" + zipFile
		zipCmd := fmt.Sprintf("cd %s/etc && zip -r %s %s/*", config.GetYamlConfig().OMC.Backup, zipFilePath, neTypeLower)

		command := fmt.Sprintf("%s&&%s", scpCmd, zipCmd)

		log.Trace("command:", command)
		out, err := global.ExecCmd(command)
		if err != nil {
			log.Error("Faile to exec command:", err)
			failureNEs = append(failureNEs, neInfo.NeType+"/"+neInfo.NeId)
			continue
		}
		log.Trace("command output:", out)

		md5Sum, err := global.GetFileMD5Sum(zipFilePath)
		if err != nil {
			log.Error("Faile to md5sum:", err)
			failureNEs = append(failureNEs, neInfo.NeType+"/"+neInfo.NeId)
			continue
		}
		//log.Debug("md5Str:", md5Sum)
		path := config.GetYamlConfig().OMC.Backup
		neBackup := dborm.NeBackup{NeType: neTypeUpper, NeId: neInfo.NeId, FileName: zipFile, Path: path, Md5Sum: md5Sum}
		_, err = dborm.XormInsertTableOne("ne_backup", neBackup)
		if err != nil {
			log.Error("Faile to XormInsertTableOne:", err)
			failureNEs = append(failureNEs, neInfo.NeType+"/"+neInfo.NeId)
			continue
		}
		successfulNEs = append(successfulNEs, neInfo.NeType+"/"+neInfo.NeId)
	}

	log.Infof("successfulNEs: %s failureNEs: %s", successfulNEs, failureNEs)
	// result
	return map[string]any{
		"successfulNEs": successfulNEs,
		"failureNEs":    failureNEs,
	}, nil
}
