package models

import (
	"time"
)

type DeviceAlarm struct {
	ID        int64     `gorm:"primary_key"`                //主键
	DID       string    `gorm:"type:varchar(32)"`           //设备编码
	TStart    time.Time `gorm:"type:datetime"`              //开始时间
	TEnd      time.Time `gorm:"type:datetime;default:null"` //结束时间
	Threshold float32   `gorm:"type:float(10,2)"`           //阈值
	SValue    float32   `gorm:"type:float(10,2)"`           //告警值
	EValue    float32   `gorm:"type:float(10,2)"`           //恢复值
	Content   string    `gorm:"type:varchar(128)"`          //告警内容
	AlarmType uint16    `gorm:"type:smallint"`              //告警类型
	Level     uint8     `gorm:"type:smallint"`              //告警等级,0:普通，1:重要，2:严重
	Sid       uint16    `gorm:"type:smallint;default:0"`    //sid
	Cid       uint16    `gorm:"type:smallint;default:0"`    //策略id
	Cname     string    `gorm:"type:varchar(40)"`           //策略名称
	LcModel
}

func (DeviceAlarm) TableName() string {
	return "t_device_alarm"
}

func (o DeviceAlarm) Update() error {
	err := G_db.Model(&o).Where("id = ?", o.ID).Updates(
		map[string]interface{}{"t_end": o.TEnd, "e_value": o.EValue}).Error
	return err
}

//用于web端告警信息同步
func GetUpdateAlarm(id uint64, update string) ([]DeviceAlarm, error) {
	var array []DeviceAlarm
	err := G_db.Model(&DeviceAlarm{}).Where("id > ? OR updated_at > ?", id, update).Order("id asc").Find(&array).Error
	return array, err
}

//获取告警信息
//flag=0获取所有告警信息
//flag=1获取结束的告警信息
//flag=2获取未结束的告警信息
func GetAlarmByCodes(codes []string, flag int) ([]DeviceAlarm, error) {
	var array []DeviceAlarm
	var err error
	switch flag {
	case 2: //未结束的告警
		err = G_db.Model(&DeviceAlarm{}).Where("d_id IN (?) AND t_end IS NULL", codes).Order("d_id asc,t_start desc").Find(&array).Error
	case 1: //已结束的告警
		err = G_db.Model(&DeviceAlarm{}).Where("d_id IN (?) AND t_end IS NOT NULL", codes).Order("d_id asc,t_start desc").Find(&array).Error
	case 0: //所有告警
		err = G_db.Model(&DeviceAlarm{}).Where("d_id IN (?)", codes).Order("d_id asc,t_start desc").Find(&array).Error
	}
	return array, err
}

type AlarmStrategy struct {
	ID       int64   `gorm:"primary_key"`      //主键
	Name     string  `gorm:"type:varchar(64)"` //策略名称
	UpLimit  float32 `gorm:"type:float(10,1)"` //上限
	LowLimit float32 `gorm:"type:float(10,1)"` //下限
	Duration uint8   `gorm:"type:int"`         //持续时间
	State    int     `gorm:"type:int"`         //1启用，0禁用
	LcModel
}

func (AlarmStrategy) TableName() string {
	return "t_alarm_strategy"
}

func (o AlarmStrategy) Delete() error {
	return G_db.Model(&o).Where("id = ?", o.ID).Updates(map[string]interface{}{"state": 0}).Error
}

func (o AlarmStrategy) IsExistedByCode() (bool, error) {
	var count int = 0
	err := G_db.Model(&o).Where(" id = ? ", o.ID).Count(&count).Error
	return count > 0, err
}

func (o AlarmStrategy) SaveFromWeb() error {
	has, err := o.IsExistedByCode()
	if err != nil {
		return err
	}
	if has {
		//更新
		return G_db.Model(&o).Updates(map[string]interface{}{
			"name": o.Name, "up_limit": o.UpLimit,
			"low_limit": o.LowLimit, "duration": o.Duration, "state": o.State}).Error
	} else {
		//插入
		return G_db.Create(&o).Error
	}
}

func GetAllAlarmStrategy() ([]AlarmStrategy, error) {
	var arr []AlarmStrategy
	if err := G_db.Model(AlarmStrategy{}).Where("state = 1").Find(&arr).Error; err != nil {
		return nil, err
	}
	return arr, nil
}

type AlarmAssociate struct {
	ID        string `gorm:"primary_key" sql:"type:varchar(32) NOT NULL"`
	Mid       int    `gorm:"primary_key" sql:"type:int"`
	Sid       int    `gorm:"primary_key" sql:"type:int"`
	Cid       int    `gorm:"primary_key" sql:"type:int"`
	State     int    `gorm:"type:int"`
	CreatedAt time.Time
	UpdatedAt time.Time
}

func (AlarmAssociate) TableName() string {
	return "t_alarm_associate"
}

//func (o AlarmAssociate) Delete() error {
//	return G_db.Model(&o).Where("id = ? AND mid = ? AND sid = ? AND cid = ?",
//		o.ID, o.Mid, o.Sid, o.Cid).Updates(map[string]interface{}{"state": 0}).Error
//}

func (o AlarmAssociate) IsExistedByCode() (bool, error) {
	var count int = 0
	err := G_db.Model(&o).Where("id = ? AND mid = ? AND sid = ? AND cid = ?",
		o.ID, o.Mid, o.Sid, o.Cid).Count(&count).Error
	return count > 0, err
}

func (o AlarmAssociate) SaveFromWeb() error {
	has, err := o.IsExistedByCode()
	if err != nil {
		return err
	}
	if has {
		//更新
		return G_db.Model(&o).Updates(map[string]interface{}{"state": o.State}).Error
	} else {
		//插入
		return G_db.Create(&o).Error
	}
}

func GetAllAlarmAssociate() ([]AlarmAssociate, error) {
	var arr []AlarmAssociate
	if err := G_db.Model(AlarmAssociate{}).Where("state = 1").Find(&arr).Error; err != nil {
		return nil, err
	}
	return arr, nil
}
