package models

import (
	"fmt"
	"time"
)

type Server struct {
	ID            int       `json:"id"`
	Name          string    `json:"name"`
	InstanceId    string    `json:"instance_id"`
	InstanceType  string    `json:"instance_type"`
	VendorId      int       `json:"vendor_id"`
	ImageId       string    `json:"image_id"`
	ImageName     string    `json:"image_name"`
	Status        string    `json:"status"`
	ZoneId        string    `json:"zone_id"`
	RegionId      string    `json:"region_id"`
	ProjectId     string    `json:"project_id"`
	Tag           string    `json:"tag"`
	App           string    `json:"app"`
	Cpu           int       `json:"cpu"`
	CpuModel      string    `json:"cpu_model"`
	Memory        int       `json:"memory"`
	SystemDisk    int       `json:"system_disk"`
	DataDisk      int       `json:"data_disk"`
	SubnetId      string    `json:"subnet_id"`
	PublicIp      string    `json:"public_ip"`
	PrivateIp     string    `json:"private_ip"`
	BandWith      int       `json:"band_with"`
	VpcId         string    `json:"vpc_id"`
	ModelName     string    `json:"model_name"`
	ModelId       string    `json:"model_id"`
	Sn            string    `json:"sn"`
	IpmiIp        string    `json:"ipmi_ip"`
	IpmiUser      string    `json:"ipmi_user"`
	CabinetName   string    `json:"cabinet_name"`
	RackName      string    `json:"rack_name"`
	ExchangerName string    `json:"exchanger_name"`
	Owner         string    `json:"owner"`
	Remark        string    `json:"remark"`
	Expired       bool      `json:"expired"`
	CreateTime    time.Time `json:"create_time"`
}

func GetServer(key string, projectId string, vendorId int, status string, zoneId string, regionId string, instanceType string, pageNum int, pageSize int) (server []Server) {
	selectSql := fmt.Sprintf(`SELECT * FROM server WHERE status != 'Deleted' and id > 0 `)
	if vendorId != 0 {
		selectSql += fmt.Sprintf(` AND vendor_id = %d`, vendorId)
	}
	if projectId != "" {
		selectSql += fmt.Sprintf(` AND project_id = '%s'`, projectId)
	}
	if instanceType != "" {
		selectSql += fmt.Sprintf(` AND instance_type = '%s'`, instanceType)
	}
	if status != "" {
		selectSql += fmt.Sprintf(` AND status = '%s'`, status)
	}
	if zoneId != "" {
		selectSql += fmt.Sprintf(` AND zone_id = '%s'`, zoneId)
	}
	if regionId != "" {
		selectSql += fmt.Sprintf(` AND region_id = '%s'`, regionId)
	}
	if key != "" {
		selectSql += fmt.Sprintf(
			` AND (name LIKE '%%%s%%' OR public_ip LIKE '%%%s%%' OR private_ip LIKE '%%%s%%' )`,
			key, key, key)
	}
	db.Raw(selectSql).Offset(pageNum).Limit(pageSize).Scan(&server)
	return
}

func GetServerTotal(key string, projectId string, vendorId int, status string, zoneId string, regionId string, instanceType string) (count int) {
	selectSql := fmt.Sprintf(`SELECT COUNT(*) FROM server WHERE status != 'Deleted' and id > 0 `)
	if vendorId != 0 {
		selectSql += fmt.Sprintf(` AND vendor_id = %d`, vendorId)
	}
	if projectId != "" {
		selectSql += fmt.Sprintf(` AND project_id = '%s'`, projectId)
	}
	if instanceType != "" {
		selectSql += fmt.Sprintf(` AND instance_type = '%s'`, instanceType)
	}
	if status != "" {
		selectSql += fmt.Sprintf(` AND status = '%s'`, status)
	}
	if zoneId != "" {
		selectSql += fmt.Sprintf(` AND zone_id = '%s'`, zoneId)
	}
	if regionId != "" {
		selectSql += fmt.Sprintf(` AND region_id = '%s'`, regionId)
	}
	if key != "" {
		selectSql += fmt.Sprintf(
			` AND (name LIKE '%%%s%%' OR public_ip LIKE '%%%s%%' OR private_ip LIKE '%%%s%%' )`,
			key, key, key)
	}
	db.Raw(selectSql).Count(&count)
	return
}

func GetServerDetail(id int) (server Server) {
	db.Where("id = ?", id).First(&server)
	return
}

func CreateServer(server interface{}, instanceId string) (err error) {
	notExist := db.Where("instance_id = ?", instanceId).First(&Server{}).RecordNotFound()
	if notExist {
		err = db.Create(server).Error
		return err
	}
	err = db.Model(&Server{}).Where("instance_id = ?", instanceId).Updates(server).Error
	return
}

func UpdateServer(id int, app string, owner string, remark string, serverIds []int) (err error) {
	if id != 0 {
		err = db.Model(&Server{}).Where("id = ?", id).Updates(Server{App: app, Owner: owner, Remark: remark}).Error
		return
	}
	err = db.Model(&Server{}).Where("id in (?)", serverIds).Updates(Server{App: app, Owner: owner, Remark: remark}).Error
	return
}

func UpdateServerStatus(serverId int, status string) (err error) {
	err = db.Model(&Server{}).Where("id = ?", serverId).Update("status", status).Error
	return
}
