package script

import (
	"github.com/spf13/cast"
	"os"
	"time"
	"wireguard-ui/component"
	"wireguard-ui/http/param"
	"wireguard-ui/service"
	"wireguard-ui/template/render_data"
)

// GenerateConfig
// @description: 生成配置文件
// @receiver script
// @return error
func (script) GenerateConfig() error {
	// 获取服务端相关配置
	serverEnt, err := service.Setting().GetWGServerForConfig()
	if err != nil {
		return err
	}

	global, err := service.Setting().GetWGSetForConfig()
	if err != nil {
		return err
	}

	// 获取客户端
	clientsEnt, _, err := service.Client().List(param.ClientList{
		Page: param.Page{
			Current: -1,
			Size:    -1,
		},
	})
	if err != nil {
		return err
	}

	var clients []render_data.Client
	for _, client := range clientsEnt {
		clients = append(clients, render_data.Client{
			ID:                  client.Id,
			Name:                client.Name,
			Email:               client.Email,
			PublicKey:           client.Keys.PublicKey,
			PresharedKey:        client.Keys.PresharedKey,
			AllowedIPS:          client.IpAllocationStr,
			Endpoint:            client.Endpoint,
			CreateUser:          client.CreateUser,
			Enabled:             cast.ToBool(client.Enabled),
			PersistentKeepalive: global.PersistentKeepalive,
			CreatedAt:           client.CreatedAt.Format("2006-01-02 15:04:05"),
			UpdatedAt:           client.UpdatedAt.Format("2006-01-02 15:04:05"),
			SyncAt:              time.Now().Format("2006-01-02 15:04:05"),
		})
	}

	execData := map[string]any{
		"Server":  serverEnt,
		"Clients": clients,
	}

	var templatePath, outFilePath string
	if os.Getenv("GIN_MODE") != "release" {
		templatePath = "E:\\Workspace\\Go\\wireguard-ui\\template\\conf\\wg.conf"
		outFilePath = "E:\\Workspace\\Go\\wireguard-ui\\template\\tmp\\wg0.conf"
	} else {
		templatePath = "./template/wg.conf"
		outFilePath = cast.ToString(global.ConfigFilePath)
	}

	// 先渲染模板
	if err = component.Template().Execute(templatePath, outFilePath, execData); err != nil {
		return nil
	}

	// 模板渲染成功，开始执行服务端控制
	component.Wireguard().ServerControl(outFilePath)
	return nil
}
