/*
 * Copyright (c) KylinSoft  Co., Ltd. 2024.All rights reserved.
 * PilotGo-plugin licensed under the Mulan Permissive Software License, Version 2. 
 * See LICENSE file for more details.
 * Author: wubijie <wubijie@kylinos.cn>
 * Date: Thu Oct 31 16:45:12 2024 +0800
 */
package controller

import (
	"gitee.com/openeuler/PilotGo/sdk/logger"
	"gitee.com/openeuler/PilotGo/sdk/response"
	"github.com/gin-gonic/gin"
	"openeuler.org/PilotGo/configmanage-plugin/global"
	"openeuler.org/PilotGo/configmanage-plugin/service"
)

type PaginationQ struct {
	Ok             bool        `json:"ok"`
	Size           int         `form:"size" json:"size"`
	CurrentPageNum int         `form:"page" json:"page"`
	Data           interface{} `json:"data"`
	TotalPage      int         `json:"total"`
}

type ConfigTypeListReq struct{}

type ConfigTypeListResp struct {
	Data []string `json:"data"`
}

// @Summary 获取配置类型列表
// @Description 获取所有支持的配置管理类型列表
// @Tags 配置管理
// @Accept json
// @Produce json
// @Success 200 {object} response.Response{data=ConfigTypeListResp} "success"
// @Router /plugin/configmanage/list/config_type [get]
func ConfigTypeListHandler(c *gin.Context) {
	result := []string{global.Repo, global.Host, global.SSH, global.SSHD, global.Sysctl, global.DNS, global.PATH}
	response.Success(c, result, "get config type success")
}

type ConfigInfosReq struct {
	Size           int    `form:"size" json:"size" binding:"required"`
	CurrentPageNum int    `form:"page" json:"page" binding:"required"`
}

// @Summary 获取配置列表(分页)
// @Description 分页获取所有配置信息列表
// @Tags 配置管理
// @Accept json
// @Produce json
// @Param size query int true "每页条数"
// @Param page query int true "当前页"
// @Success 200 {object} response.Response{data=PaginationQ} "success"
// @Router /plugin/configmanage/list/config_infos [get]
func ConfigInfosHandler(c *gin.Context) {
	p := &PaginationQ{}
	err := c.ShouldBindQuery(p)
	if err != nil {
		response.Fail(c, "parameter error", err.Error())
		return
	}
	num := p.Size * (p.CurrentPageNum - 1)
	total, data, err := service.GetInfos(num, p.Size)
	if err != nil {
		response.Fail(c, "parameter error", err.Error())
		return
	}
	p.Data = data
	p.TotalPage = total

	response.Success(c, p, "get config success")
}

type ConfigInfoReq struct {
	UUID string `json:"uuid" binding:"required"`
}

// @Summary 获取配置详情
// @Description 根据配置UUID获取配置详细信息
// @Tags 配置管理
// @Accept json
// @Produce json
// @Param body body ConfigInfoReq true "配置UUID"
// @Success 200 {object} response.Response "success"
// @Router /plugin/configmanage/list/config_info [post]
func ConfigInfoHandler(c *gin.Context) {
	query := &struct {
		UUID string `json:"uuid"`
	}{}
	err := c.ShouldBindJSON(query)
	if err != nil {
		response.Fail(c, "parameter error", err.Error())
		return
	}
	logger.Debug("load config")

	ci, err := service.GetConfigByUUID(query.UUID)
	if err != nil {
		logger.Error("failed to get configinfo: %s", err.Error())
		response.Fail(c, "get configinfo fail:", err.Error())
		return
	}
	switch ci.Type {
	case global.Repo:
		repofiles, err := service.GetRopeFilesByConfigUUID(ci.UUID)
		if err != nil {
			logger.Error("failed to get repoconfig files: %s", err.Error())
			response.Fail(c, "failed to get repoconfig files", err.Error())
			return
		}
		logger.Debug("load repoconfig success")
		response.Success(c, repofiles, "load repo config success")

	case global.Host:
		hostfiles, err := service.GetHostFilesByConfigUUID(ci.UUID)
		if err != nil {
			logger.Error("failed to get hostconfig files: %s", err.Error())
			response.Fail(c, "failed to get hostconfig files", err.Error())
			return
		}
		logger.Debug("load hostconfig success")
		response.Success(c, hostfiles, "load hostconfig success")

	case global.SSH:
		sshfiles, err := service.GetSSHFilesByConfigUUID(ci.UUID)
		if err != nil {
			logger.Error("failed to get sshconfig files: %s", err.Error())
			response.Fail(c, "failed to get sshconfig files", err.Error())
			return
		}
		logger.Debug("load sshconfig success")
		response.Success(c, sshfiles, "load sshconfig success")

	case global.SSHD:
		sshdfiles, err := service.GetSSHDFilesByConfigUUID(ci.UUID)
		if err != nil {
			logger.Error("failed to get sshdconfig files: %s", err.Error())
			response.Fail(c, "failed to get sshdconfig files", err.Error())
			return
		}
		logger.Debug("load sshdconfig success")
		response.Success(c, sshdfiles, "load sshdconfig success")

	case global.Sysctl:
		sysctlfiles, err := service.GetSysctlFilesByConfigUUID(ci.UUID)
		if err != nil {
			logger.Error("failed to get sysctlconfig files: %s", err.Error())
			response.Fail(c, "failed to get sysctlconfig files", err.Error())
			return
		}
		logger.Debug("load sysctlconfig success")
		response.Success(c, sysctlfiles, "load sysctlconfig success")

	case global.DNS:
		dnsfiles, err := service.GetDNSFilesByConfigUUID(ci.UUID)
		if err != nil {
			logger.Error("failed to get dnsfiles files: %s", err.Error())
			response.Fail(c, "failed to get dnsfiles files", err.Error())
			return
		}
		logger.Debug("load dnsfiles success")
		response.Success(c, dnsfiles, "load dnsfiles success")

	case global.PATH:
		pathfiles, err := service.GetPathFilesByConfigUUID(ci.UUID)
		if err != nil {
			logger.Error("failed to get pathfiles files: %s", err.Error())
			response.Fail(c, "failed to get pathfiles files", err.Error())
			return
		}
		logger.Debug("load pathfiles success")
		response.Success(c, pathfiles, "load pathfiles success")

	default:
		response.Fail(c, nil, "Unknown type of configinfo:"+query.UUID)
	}
}

type ConfigHistoryReq struct {
	UUID string `json:"node_uuid" binding:"required"`
	Type string `json:"type" binding:"required"`
}

// @Summary 获取配置历史
// @Description 查看某台机器某种类型的历史配置信息
// @Tags 配置管理
// @Accept json
// @Produce json
// @Param body body ConfigHistoryReq true "节点UUID和配置类型"
// @Success 200 {object} response.Response "success"
// @Router /plugin/configmanage/list/config_history [post]
func ConfigHistoryHandler(c *gin.Context) {
	query := &struct {
		UUID string `json:"node_uuid"`
		Type string `json:"type"`
	}{}
	err := c.ShouldBindJSON(query)
	if err != nil {
		response.Fail(c, "parameter error", err.Error())
		return
	}
	logger.Debug("load config")

	switch query.Type {
	case global.Repo:
		repofiles, err := service.GetRopeFilesByNode(query.UUID)
		if err != nil {
			logger.Error("failed to get repoconfig files: %s", err.Error())
			response.Fail(c, "failed to get repoconfig files", err.Error())
			return
		}
		logger.Debug("load repoconfig success")
		response.Success(c, repofiles, "load repo config success")

	case global.Host:
		hostconfig, err := service.GetHostFilesByNode(query.UUID)
		if err != nil {
			logger.Error("failed to get hostconfig files: %s", err.Error())
			response.Fail(c, "failed to get hostconfig files", err.Error())
			return
		}
		logger.Debug("load hostconfig success")
		response.Success(c, hostconfig, "load hostconfig success")

	case global.SSH:
		sshconfig, err := service.GetSSHFilesByNode(query.UUID)
		if err != nil {
			logger.Error("failed to get sshconfig files: %s", err.Error())
			response.Fail(c, "failed to get sshconfig files", err.Error())
			return
		}
		logger.Debug("load sshconfig success")
		response.Success(c, sshconfig, "load sshconfig success")

	case global.SSHD:
		sshdconfig, err := service.GetSSHDFilesByNode(query.UUID)
		if err != nil {
			logger.Error("failed to get sshdconfig files: %s", err.Error())
			response.Fail(c, "failed to get sshdconfig files", err.Error())
			return
		}
		logger.Debug("load sshdconfig success")
		response.Success(c, sshdconfig, "load sshdconfig success")

	case global.Sysctl:
		sysctlfiles, err := service.GetSysctlFilesByNode(query.UUID)
		if err != nil {
			logger.Error("failed to get sysctlconfig files: %s", err.Error())
			response.Fail(c, "failed to get sysctlconfig files", err.Error())
			return
		}
		logger.Debug("load sysctlconfig success")
		response.Success(c, sysctlfiles, "load sysctlconfig success")

	case global.DNS:
		dnsconfig, err := service.GetDNSFilesByNode(query.UUID)
		if err != nil {
			logger.Error("failed to get dnsconfig files: %s", err.Error())
			response.Fail(c, "failed to get dnsconfig files", err.Error())
			return
		}
		logger.Debug("load dnsconfig success")
		response.Success(c, dnsconfig, "load dnsconfig success")

	case global.PATH:
		pathconfig, err := service.GetPathFilesByNode(query.UUID)
		if err != nil {
			logger.Error("failed to get pathconfig files: %s", err.Error())
			response.Fail(c, "failed to get pathconfig files", err.Error())
			return
		}
		logger.Debug("load pathconfig success")
		response.Success(c, pathconfig, "load pathconfig success")

	default:
		response.Fail(c, nil, "Unknown type of configinfo:"+query.UUID)
	}
}