package model

import (
	"database/sql"
	"errors"
)

type RedisCfg struct {
	Model
}

type RedisCfgRow struct {
	Id                 int64
	Address            string
	Remark             string
	Password           string
	MaxConnectWait     int64
	MaxStatusFailed    int64
	MinMemoryFree      int64
	StepMemoryIncrease int64
	MaxMemoryUsage     int64
	MaxConnection      int64
	MaxEviIncreased    int64
	MaxQPS             int64
	MailList           string
	Disabled           bool
}

func NewRedisCfg(db *sql.DB) *RedisCfg {
	return &RedisCfg{
		Model{
			db: db,
		},
	}
}

func (m *RedisCfg) Insert(row *RedisCfgRow) (int64, error) {
	if row.Address == "" {
		return 0, errors.New("Address不能为空")
	}
	disabledInt := 0
	if row.Disabled {
		disabledInt = 1
	}
	ret, err := m.db.Exec(`INSERT INTO rediscfg(
			address,
			remark,
			password,
			max_connect_wait,
			max_status_failed,
			min_memory_free,
			step_memory_increase,
			max_memory_usage,
			max_connection,
			max_evi_increased,
			max_qps,
			mail_list,
			disabled
		) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)`,
		row.Address,
		row.Remark,
		row.Password,
		row.MaxConnectWait,
		row.MaxStatusFailed,
		row.MinMemoryFree,
		row.StepMemoryIncrease,
		row.MaxMemoryUsage,
		row.MaxConnection,
		row.MaxEviIncreased,
		row.MaxQPS,
		row.MailList,
		disabledInt,
	)
	if err != nil {
		return 0, err
	}
	return ret.LastInsertId()
}

func (m *RedisCfg) Update(row *RedisCfgRow) (int64, error) {
	if row.Id <= 0 {
		return 0, errors.New("ID必须是大于0的整数")
	}
	if row.Address == "" {
		return 0, errors.New("Address不能为空")
	}
	disabledInt := 0
	if row.Disabled {
		disabledInt = 1
	}
	ret, err := m.db.Exec(`UPDATE rediscfg SET
			address=?,
			remark=?,
			password=?,
			max_connect_wait=?,
			max_status_failed=?,
			min_memory_free=?,
			step_memory_increase=?,
			max_memory_usage=?,
			max_connection=?,
			max_evi_increased=?,
			max_qps=?,
			mail_list=?,
			disabled=?
		WHERE id=?`,
		row.Address,
		row.Remark,
		row.Password,
		row.MaxConnectWait,
		row.MaxStatusFailed,
		row.MinMemoryFree,
		row.StepMemoryIncrease,
		row.MaxMemoryUsage,
		row.MaxConnection,
		row.MaxEviIncreased,
		row.MaxQPS,
		row.MailList,
		disabledInt,
		row.Id,
	)
	if err != nil {
		return 0, nil
	}
	return ret.RowsAffected()
}

func (m *RedisCfg) Delete(id int64) (int64, error) {
	if id <= 0 {
		return 0, errors.New("ID必须是大于0的整数")
	}
	ret, err := m.db.Exec("DELETE FROM rediscfg WHERE id=?", id)
	if err != nil {
		return 0, err
	}
	return ret.RowsAffected()
}

func (m *RedisCfg) Get(id int64) (*RedisCfgRow, error) {
	if id <= 0 {
		return nil, errors.New("ID必须是大于0的整数")
	}
	result := m.db.QueryRow(`SELECT id,
				address,
				remark,
				password,
				max_connect_wait,
				max_status_failed,
				min_memory_free,
				step_memory_increase,
				max_memory_usage,
				max_connection,
				max_evi_increased,
				max_qps,
				mail_list,
				disabled
			FROM rediscfg WHERE id=?`,
		id,
	)
	row := RedisCfgRow{}
	err := result.Scan(
		&row.Id,
		&row.Address,
		&row.Remark,
		&row.Password,
		&row.MaxConnectWait,
		&row.MaxStatusFailed,
		&row.MinMemoryFree,
		&row.StepMemoryIncrease,
		&row.MaxMemoryUsage,
		&row.MaxConnection,
		&row.MaxEviIncreased,
		&row.MaxQPS,
		&row.MailList,
		&row.Disabled,
	)
	if err != nil {
		if err == sql.ErrNoRows {
			return nil, errors.New("记录不存在")
		} else {
			return nil, err
		}
	} else {
		return &row, nil
	}
}

func (m *RedisCfg) GetAll(disabledInt int) ([]*RedisCfgRow, error) {
	var sql string
	if disabledInt < 0 {
		sql = `SELECT id,
			address,
			remark,
			password,
			max_connect_wait,
			max_status_failed,
			min_memory_free,
			step_memory_increase,
			max_memory_usage,
			max_connection,
			max_evi_increased,
			max_qps,
			mail_list,
			disabled
		FROM rediscfg WHERE disabled>? ORDER BY id`
	} else {
		sql = `SELECT id,
			address,
			remark,
			password,
			max_connect_wait,
			max_status_failed,
			min_memory_free,
			step_memory_increase,
			max_memory_usage,
			max_connection,
			max_evi_increased,
			max_qps,
			mail_list,
			disabled
		FROM rediscfg WHERE disabled=? ORDER BY id`
	}
	result, err := m.db.Query(sql, disabledInt)
	if err != nil {
		return nil, err
	}
	rows := make([]*RedisCfgRow, 0)
	for result.Next() {
		row := RedisCfgRow{}
		err = result.Scan(
			&row.Id,
			&row.Address,
			&row.Remark,
			&row.Password,
			&row.MaxConnectWait,
			&row.MaxStatusFailed,
			&row.MinMemoryFree,
			&row.StepMemoryIncrease,
			&row.MaxMemoryUsage,
			&row.MaxConnection,
			&row.MaxEviIncreased,
			&row.MaxQPS,
			&row.MailList,
			&row.Disabled,
		)
		if err != nil {
			continue
		}
		rows = append(rows, &row)
	}
	return rows, nil
}
