package model

import (
	"database/sql"
	"errors"
	"fmt"
	"time"
)

type WarnLog struct {
	Model
}

type WarnLogRow struct {
	Id           int64
	RedisId      int64
	RedisAddress string
	RedisRemark  string
	WarnTime     int64
	WarnMsg      string
}

func NewWarnLog(db *sql.DB) *WarnLog {
	return &WarnLog{
		Model{
			db: db,
		},
	}
}

func (m *WarnLog) Add(row *WarnLogRow) (int64, error) {
	if row.RedisId <= 0 {
		return 0, errors.New("Redis的ID必须是正整数")
	}
	if row.WarnMsg == "" {
		return 0, errors.New("报警内容不能为空")
	}
	if row.WarnTime <= 0 {
		row.WarnTime = time.Now().Unix()
	}
	ret, err := m.db.Exec("INSERT INTO warnlog(redis_id,warn_time,warn_msg) VALUES(?,?,?)", row.RedisId, row.WarnTime, row.WarnMsg)
	if err != nil {
		return 0, err
	} else {
		return ret.LastInsertId()
	}
}

func (m *WarnLog) CleanUntil(until int64) (int64, error) {
	ret, err := m.db.Exec("DELETE FROM warnlog WHERE warn_time<?", until)
	if err != nil {
		return 0, err
	} else {
		return ret.RowsAffected()
	}
}

func (m *WarnLog) Count(redisId int64) (int64, error) {
	var (
		row *sql.Row
		cnt int64
	)
	if redisId == 0 {
		row = m.db.QueryRow("SELECT COUNT(*) FROM warnlog")
	} else {
		row = m.db.QueryRow("SELECT COUNT(*) FROM warnlog WHERE redis_id=?", redisId)
	}
	if err := row.Scan(&cnt); err != nil {
		return 0, err
	} else {
		return cnt, nil
	}
}

func (m *WarnLog) GetList(redisId int64, offset int64, limit int64, orderDesc bool) ([]*WarnLogRow, error) {
	var (
		orderDir string
		ret      *sql.Rows
		err      error
	)
	if orderDesc {
		orderDir = "DESC"
	} else {
		orderDir = "ASC"
	}
	if redisId == 0 {
		if limit > 0 {
			sql := fmt.Sprintf("SELECT warnlog.id,warnlog.redis_id,warnlog.warn_time,warnlog.warn_msg,rediscfg.address,rediscfg.remark FROM warnlog INNER JOIN rediscfg ON warnlog.redis_id=rediscfg.id ORDER BY warnlog.id %s LIMIT ?,?", orderDir)
			ret, err = m.db.Query(sql, offset, limit)
		} else {
			sql := fmt.Sprintf("SELECT warnlog.id,warnlog.redis_id,warnlog.warn_time,warnlog.warn_msg,rediscfg.address,rediscfg.remark FROM warnlog INNER JOIN rediscfg ON warnlog.redis_id=rediscfg.id ORDER BY warnlog.id %s", orderDir)
			ret, err = m.db.Query(sql)
		}

	} else {
		if limit > 0 {
			sql := fmt.Sprintf("SELECT warnlog.id,warnlog.redis_id,warnlog.warn_time,warnlog.warn_msg,rediscfg.address,rediscfg.remark FROM warnlog INNER JOIN rediscfg ON warnlog.redis_id=rediscfg.id WHERE warnlog.redis_id=? ORDER BY warnlog.id %s LIMIT ?,?", orderDir)
			ret, err = m.db.Query(sql, redisId, offset, limit)
		} else {
			sql := fmt.Sprintf("SELECT warnlog.id,warnlog.redis_id,warnlog.warn_time,warnlog.warn_msg,rediscfg.address,rediscfg.remark FROM warnlog INNER JOIN rediscfg ON warnlog.redis_id=rediscfg.id WHERE warnlog.redis_id=? ORDER BY warnlog.id %s", orderDir)
			ret, err = m.db.Query(sql, redisId)
		}
	}
	if err != nil {
		return nil, err
	} else {
		rows := make([]*WarnLogRow, 0)
		for ret.Next() {
			row := WarnLogRow{}
			err = ret.Scan(&row.Id, &row.RedisId, &row.WarnTime, &row.WarnMsg, &row.RedisAddress, &row.RedisRemark)
			if err != nil {
				continue
			}
			rows = append(rows, &row)
		}
		return rows, nil
	}
}
