package repo

import (
	"strings"

	"ems.agt/features/firewall/model"
	"ems.agt/lib/core/datasource"
	"ems.agt/lib/log"
)

// 实例化数据层 RepoFirewall 结构体
var NewRepoFirewall = &RepoFirewall{
	selectSql: `select 
	id, created_at, updated_at, type, port, protocol, address, strategy, description 
	from monitor_firewall`,

	resultMap: map[string]string{
		"id":          "ID",
		"created_at":  "CreatedAt",
		"updated_at":  "UpdatedAt",
		"type":        "Type",
		"port":        "Port",
		"protocol":    "Protocol",
		"address":     "Address",
		"strategy":    "Strategy",
		"description": "Description",
	},
}

// RepoFirewall 防火墙 数据层处理
type RepoFirewall struct {
	// 查询视图对象SQL
	selectSql string
	// 结果字段与实体映射
	resultMap map[string]string
}

// convertResultRows 将结果记录转实体结果组
func (r *RepoFirewall) convertResultRows(rows []map[string]any) []model.Firewall {
	arr := make([]model.Firewall, 0)
	for _, row := range rows {
		UdmUser := model.Firewall{}
		for key, value := range row {
			if keyMapper, ok := r.resultMap[key]; ok {
				datasource.SetFieldValue(&UdmUser, keyMapper, value)
			}
		}
		arr = append(arr, UdmUser)
	}
	return arr
}

// List 根据实体查询
func (r *RepoFirewall) List(f model.Firewall) []model.Firewall {
	// 查询条件拼接
	var conditions []string
	var params []any
	if f.Type != "" {
		conditions = append(conditions, "type = ?")
		params = append(params, f.Type)
	}
	if f.Protocol != "" {
		conditions = append(conditions, "protocol = ?")
		params = append(params, f.Protocol)
	}

	// 构建查询条件语句
	whereSql := ""
	if len(conditions) > 0 {
		whereSql += " where " + strings.Join(conditions, " and ")
	}

	// 查询数据
	querySql := r.selectSql + whereSql
	results, err := datasource.RawDB("", querySql, params)
	if err != nil {
		log.Errorf("query err => %v", err)
	}

	// 转换实体
	return r.convertResultRows(results)
}

// Insert 新增实体
func (r *RepoFirewall) Insert(f model.Firewall) int64 {
	results, err := datasource.DefaultDB().Table("monitor_firewall").Insert(f)
	if err != nil {
		return results
	}
	return results
}

// Update 修改更新
func (r *RepoFirewall) Update(f model.Firewall) int64 {
	// 查询先
	var fd model.Firewall
	if f.Type == "port" {
		has, err := datasource.DefaultDB().Table("monitor_firewall").Where("type = ? AND port = ? AND protocol = ? AND address = ? AND strategy = ?", "port", f.Port, f.Protocol, f.Address, f.Strategy).Get(&fd)
		if !has || err != nil {
			return 0
		}
	} else {
		has, err := datasource.DefaultDB().Table("monitor_firewall").Where("type = ? AND address = ? AND strategy = ?", "address", f.Address, f.Strategy).Get(&fd)
		if !has || err != nil {
			return 0
		}
	}
	f.ID = fd.ID

	results, err := datasource.DefaultDB().Table("monitor_firewall").Where("id = ?", f.ID).Update(f)
	if err != nil {
		return 0
	}
	return results
}

// Delete 删除实体
func (r *RepoFirewall) Delete(id int64) int64 {
	results, err := datasource.DefaultDB().Table("u_sub_user").Where("id = ?", id).Delete()
	if err != nil {
		return results
	}
	return results
}

// DeleteFirewallRecord 删除实体
func (r *RepoFirewall) DeleteFirewallRecord(fType, port, protocol, address, strategy string) int64 {
	results, err := datasource.DefaultDB().Table("u_sub_user").Where("type = ? AND port = ? AND protocol = ? AND address = ? AND strategy = ?", fType, port, protocol, address, strategy).Delete()
	if err != nil {
		return results
	}
	return results
}
