package dbrest

import (
	"archive/tar"
	"compress/gzip"
	"io"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"time"

	"nms_nbi/lib/core/conf"
	"nms_nbi/lib/dborm"
	"nms_nbi/lib/log"
	"nms_nbi/lib/services"
	"nms_nbi/restagent/config"

	_ "github.com/go-sql-driver/mysql"
)

var (
	// 系统备份-数据库备份
	UriDbBackup       = config.DefaultUriPrefix + "/dataManagement/{apiVersion}/dbBackup"
	CustomUriDbBackup = config.UriPrefix + "/dataManagement/{apiVersion}/dbBackup" // for external

	// 系统备份-文件备份
	UriConfBackup       = config.DefaultUriPrefix + "/dataManagement/{apiVersion}/confBackup"
	CustomUriConfBackup = config.UriPrefix + "/dataManagement/{apiVersion}/confBackup" // for external

)

// DbBackup 系统备份-数据库备份1
func DbBackup(w http.ResponseWriter, r *http.Request) {
	dbConfigHost := conf.Get("database.host").(string)
	dbConfigUser := conf.Get("database.user").(string)
	dbConfigPassword := conf.Get("database.password").(string)
	dbConfigBackup := conf.Get("database.backup").(string)

	// 备份SQL文件路径
	fileName := "database_backup_" + time.Now().Format("20060102150405") + ".sql"
	backupFile := dbConfigBackup + "/" + fileName

	// 执行mysqldump命令进行备份
	cmd := exec.Command("mysqldump", "-u", dbConfigUser, "-p"+dbConfigPassword, "-h", dbConfigHost, "--all-databases", ">", backupFile)
	err := cmd.Start()
	if err != nil {
		services.ResponseErrorWithJson(w, 400, err.Error())
		return
	}

	// 备份结果
	res, err := dborm.DbClient.XEngine.Exec("INSERT INTO `sys_backup`(`id`, `created_at`, `updated_at`, `backup_type`, `backup_way`, `name`, `path`) VALUES (null, ?, ?,  '1',  '0', ?, ?);", time.Now(), time.Now(), fileName, backupFile)
	if err != nil {
		services.ResponseErrorWithJson(w, 500, err.Error())
		return
	}
	services.ResponseWithJson(w, 200, res)
	log.Info("Backup completed successfully.")
}

// 系统备份-文件备份0
func ConfBackup(w http.ResponseWriter, r *http.Request) {
	dbConfigBackup := conf.Get("database.backup").(string)
	etcDir := conf.Get("ne.omcdir").(string)

	// 文件名
	fileName := "conf_backup_" + time.Now().Format("20060102150405") + ".tar.gz"
	backupFile := dbConfigBackup + "/" + fileName

	err := createTarGz(etcDir, backupFile)
	if err != nil {
		services.ResponseErrorWithJson(w, 500, err.Error())
		return
	}

	// 备份结果
	res, err := dborm.DbClient.XEngine.Exec("INSERT INTO `sys_backup`(`id`, `created_at`, `updated_at`, `backup_type`, `backup_way`, `name`, `path`) VALUES (null, ?, ?,  '1',  '0', ?, ?);", time.Now(), time.Now(), fileName, backupFile)
	if err != nil {
		services.ResponseErrorWithJson(w, 500, err.Error())
		return
	}
	services.ResponseWithJson(w, 200, res)
	log.Info("Backup completed successfully.")
}

// 打压缩
func createTarGz(source, target string) error {
	tarFile, err := os.Create(target)
	if err != nil {
		return err
	}
	defer tarFile.Close()

	gw := gzip.NewWriter(tarFile)
	defer gw.Close()

	tw := tar.NewWriter(gw)
	defer tw.Close()

	return filepath.Walk(source, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		header, err := tar.FileInfoHeader(info, "")
		if err != nil {
			return err
		}

		relPath, err := filepath.Rel(source, path)
		if err != nil {
			return err
		}

		header.Name = relPath

		if err := tw.WriteHeader(header); err != nil {
			return err
		}

		if !info.Mode().IsRegular() {
			return nil
		}

		file, err := os.Open(path)
		if err != nil {
			return err
		}
		defer file.Close()

		_, err = io.Copy(tw, file)
		return err
	})
}
