package service

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

	"be.ems/src/framework/cmd"
	"be.ems/src/framework/utils/date"
	"be.ems/src/framework/utils/file"
	"be.ems/src/modules/ne/model"
	"be.ems/src/modules/ne/repository"
)

// 实例化服务层 NeConfigBackup 结构体
var NewNeConfigBackup = &NeConfigBackup{
	neConfigBackupRepository: repository.NewNeConfigBackup,
}

// NeConfigBackup 网元配置文件备份记录 服务层处理
type NeConfigBackup struct {
	neConfigBackupRepository *repository.NeConfigBackup // 网元配置文件备份记录
}

// FindByPage 分页查询列表数据
func (s NeConfigBackup) FindByPage(query map[string]string) ([]model.NeConfigBackup, int64) {
	return s.neConfigBackupRepository.SelectByPage(query)
}

// FindById 通过ID查询
func (s NeConfigBackup) FindById(id int64) model.NeConfigBackup {
	if id <= 0 {
		return model.NeConfigBackup{}
	}
	arr := s.neConfigBackupRepository.SelectByIds([]int64{id})
	if len(arr) > 0 {
		return arr[0]
	}
	return model.NeConfigBackup{}
}

// Insert 新增信息
func (s NeConfigBackup) Insert(item model.NeConfigBackup) int64 {
	return s.neConfigBackupRepository.Insert(item)
}

// Update 修改信息
func (s NeConfigBackup) Update(item model.NeConfigBackup) int64 {
	return s.neConfigBackupRepository.Update(item)
}

// DeleteByIds 批量删除信息
func (s NeConfigBackup) DeleteByIds(ids []int64) (int64, error) {
	// 检查是否存在
	data := s.neConfigBackupRepository.SelectByIds(ids)
	if len(data) <= 0 {
		return 0, fmt.Errorf("neConfigBackup.noData")
	}

	if len(data) == len(ids) {
		rows := s.neConfigBackupRepository.DeleteByIds(ids)
		return rows, nil
	}
	// 删除信息失败！
	return 0, fmt.Errorf("delete fail")
}

// FileLocalToNe 网元配置文件复制到网元端覆盖
func (s NeConfigBackup) FileLocalToNe(neInfo model.NeInfo, localFile string) error {
	neTypeLower := strings.ToLower(neInfo.NeType)
	// 网管本地路径
	omcPath := "/usr/local/omc/backup/ne_config"
	if runtime.GOOS == "windows" {
		omcPath = fmt.Sprintf("C:%s", omcPath)
	}
	localDirPath := fmt.Sprintf("%s/%s/%s/backup/tmp_import", omcPath, neTypeLower, neInfo.NeId)
	if err := file.UnZip(localFile, localDirPath); err != nil {
		return fmt.Errorf("unzip err")
	}

	// 本地复制到网元端
	if err := s.FileLocalToNePath(neInfo, localDirPath); err != nil {
		return err
	}

	_ = os.RemoveAll(localDirPath) // 删除本地临时目录
	return nil
}

// FileNeToLocal 网元备份文件网元端复制到本地
func (s NeConfigBackup) FileNeToLocal(neInfo model.NeInfo) (string, error) {
	neTypeLower := strings.ToLower(neInfo.NeType)
	// 网管本地路径
	omcPath := "/usr/local/omc/backup/ne_config"
	if runtime.GOOS == "windows" {
		omcPath = fmt.Sprintf("C:%s", omcPath)
	}
	localDirPath := fmt.Sprintf("%s/%s/%s/from_ne_tmp", omcPath, neTypeLower, neInfo.NeId)

	// 网元端复制到本地
	if err := s.FileNeToLocalPath(neInfo, localDirPath); err != nil {
		return "", err
	}

	// 压缩zip文件名
	zipFileName := fmt.Sprintf("%s-%s-etc-%s.zip", neTypeLower, neInfo.NeId, date.ParseDateToStr(time.Now(), date.YYYYMMDDHHMMSS))
	zipFilePath := fmt.Sprintf("%s/%s/%s/%s", omcPath, neTypeLower, neInfo.NeId, zipFileName)
	if err := file.CompressZipByDir(zipFilePath, localDirPath); err != nil {
		return "", fmt.Errorf("compress zip err")
	}

	_ = os.RemoveAll(localDirPath) // 删除本地临时目录
	return zipFilePath, nil
}

// FileNeToLocalPath 网元备份文件网元端复制到本地路径
func (s NeConfigBackup) FileNeToLocalPath(neInfo model.NeInfo, localDirPath string) error {
	neTypeLower := strings.ToLower(neInfo.NeType)

	// 网元配置文件先复制到临时目录
	cmd.Exec("sudo mkdir -p /tmp/omc/ne_config && sudo chmod 777 -R /tmp/omc")
	neDirTemp := fmt.Sprintf("/tmp/omc/ne_config/%s/%s", neTypeLower, neInfo.NeId)
	switch neTypeLower {
	case "ims":
		// ims目录
		cmd.Exec(fmt.Sprintf("mkdir -p %s/ims", neDirTemp))
		imsDirArr := [...]string{"bgcf", "icscf", "ismc", "mmtel", "mrf", "oam_manages.yaml", "pcscf", "scscf", "vars.cfg", "zlog"}
		for _, v := range imsDirArr {
			cmd.Exec(fmt.Sprintf("sudo cp -rf /usr/local/etc/ims/%s %s/ims", v, neDirTemp))
		}
		// mf目录
		cmd.Exec(fmt.Sprintf("mkdir -p %s/mf && sudo cp -rf /usr/local/etc/mf %s", neDirTemp, neDirTemp))
		// rtproxy目录
		cmd.Exec(fmt.Sprintf("mkdir -p %s/rtproxy && sudo cp -rf /usr/local/etc/rtproxy/rtproxy.conf %s/rtproxy", neDirTemp, neDirTemp))
		// iwf目录
		cmd.Exec(fmt.Sprintf("mkdir -p %s/iwf && sudo cp -rf /usr/local/etc/iwf/*.yaml %s/iwf", neDirTemp, neDirTemp))
	case "udm":
		// udm目录
		cmd.Exec(fmt.Sprintf("mkdir -p %s && sudo cp -rf /usr/local/etc/udm/*.yaml %s", neDirTemp, neDirTemp))
		// kvdb目录
		cmd.Exec(fmt.Sprintf("mkdir -p %s/kvdb && sudo cp -rf /usr/local/etc/kvdb/*.{rdb,conf} %s/kvdb", neDirTemp, neDirTemp))
		cmd.Exec(fmt.Sprintf("mkdir -p %s/kvdb && sudo cp -rf /usr/local/etc/kvdb/log %s/kvdb", neDirTemp, neDirTemp))
	case "smsc":
		cmd.Exec(fmt.Sprintf("mkdir -p %s && sudo cp -rf /usr/local/etc/smsc/{*.yaml,*.conf,*conf.txt} %s", neDirTemp, neDirTemp))
		cmd.Exec(fmt.Sprintf("sudo cp -rf /usr/local/etc/smsc/conf %s/conf", neDirTemp))
	default:
		nePath := fmt.Sprintf("/usr/local/etc/%s/*.yaml", neTypeLower)
		if neTypeLower == "amf" {
			nePath = fmt.Sprintf("/usr/local/etc/%s/*.{yaml,csv}", neTypeLower)
		}
		if neTypeLower == "mme" {
			nePath = fmt.Sprintf("/usr/local/etc/%s/*.{yaml,conf,csv}", neTypeLower)
		}
		cmd.Exec(fmt.Sprintf("mkdir -p %s && sudo cp -rf %s %s", neDirTemp, nePath, neDirTemp))
	}

	// 网元端复制到本地
	if err := file.CopyDir(neDirTemp, localDirPath); err != nil {
		return fmt.Errorf("copy config from ne err")
	}
	cmd.Exec(fmt.Sprintf("sudo rm -rf %s", neDirTemp)) // 删除临时目录
	return nil
}

// FileLocalToNePath 网元备份文件本地路径复制到网元端
func (s NeConfigBackup) FileLocalToNePath(neInfo model.NeInfo, localDirPath string) error {
	neTypeLower := strings.ToLower(neInfo.NeType)

	// 网元配置端上的临时目录
	neDirTemp := fmt.Sprintf("/tmp/omc/ne_config/%s/%s", neTypeLower, neInfo.NeId)
	cmd.Exec(fmt.Sprintf("sudo mkdir -p %s && sudo chmod 777 -R /tmp/omc && sudo rm -rf %s", neDirTemp, neDirTemp))
	// 复制到网元端
	if err := file.CopyDir(localDirPath, neDirTemp); err != nil {
		return fmt.Errorf("copy config to ne err")
	}

	// 配置复制到网元内
	switch neTypeLower {
	case "ims":
		// ims目录
		imsDirArr := [...]string{"bgcf", "icscf", "ismc", "mmtel", "mrf", "oam_manager.yaml", "pcscf", "scscf", "vars.cfg", "zlog"}
		for _, v := range imsDirArr {
			cmd.Exec(fmt.Sprintf("sudo mkdir -p /usr/local/etc/ims && sudo cp -rf %s/ims/%s /usr/local/etc/ims/%v && sudo chmod 777 -R /usr/local/etc/ims/%s", neDirTemp, v, v, v))
		}
		// mf目录
		cmd.Exec(fmt.Sprintf("sudo mkdir -p /usr/local/etc/mf && sudo cp -rf %s/mf/* /usr/local/etc/mf && sudo chmod 777 -R /usr/local/etc/mf", neDirTemp))
		// rtproxy目录
		cmd.Exec(fmt.Sprintf("sudo mkdir -p /usr/local/etc/rtproxy && sudo cp -rf %s/rtproxy/* /usr/local/etc/rtproxy && sudo chmod 777 /usr/local/etc/rtproxy/rtproxy.conf", neDirTemp))
		// iwf目录
		cmd.Exec(fmt.Sprintf("sudo mkdir -p /usr/local/etc/iwf && sudo cp -rf %s/iwf/* /usr/local/etc/iwf && sudo chmod 777 /usr/local/etc/iwf/*.yaml", neDirTemp))
	case "smsc":
		chmodFile := "sudo chmod 777 /usr/local/etc/smsc/{*sys.conf,*conf.txt,conf/is41_operation.conf}"
		cmd.Exec(fmt.Sprintf("sudo mkdir -p /usr/local/etc/smsc/conf && sudo cp -rf %s/* /usr/local/etc/smsc && %s", neDirTemp, chmodFile))
	case "udm":
		// udm目录
		chmodFile := "sudo chmod 777 /usr/local/etc/udm/*.yaml"
		cmd.Exec(fmt.Sprintf("sudo cp -rf %s/*.yaml /usr/local/etc/udm && %s", neDirTemp, chmodFile))
		// kvdb目录
		cmd.Exec(fmt.Sprintf("sudo mkdir -p /usr/local/etc/kvdb && sudo cp -rf %s/kvdb/* /usr/local/etc/kvdb && sudo chmod 777 /usr/local/etc/kvdb/*.{rdb,conf}", neDirTemp))
	default:
		neEtcPath := fmt.Sprintf("/usr/local/etc/%s", neTypeLower)
		chmodFile := fmt.Sprintf("sudo chmod 777 %s/*.yaml", neEtcPath)
		if neTypeLower == "amf" {
			chmodFile = fmt.Sprintf("sudo chmod 777 %s/*.{yaml,csv}", neEtcPath)
		}
		if neTypeLower == "mme" {
			chmodFile = fmt.Sprintf("sudo chmod 777 %s/*.{yaml,conf,csv}", neEtcPath)
		}
		cmd.Exec(fmt.Sprintf("sudo cp -rf %s/* %s && %s", neDirTemp, neEtcPath, chmodFile))
	}

	cmd.Exec(fmt.Sprintf("sudo rm -rf %s", neDirTemp)) // 删除临时目录
	return nil
}
