package model

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

type SysLog struct {
	Model
}

type SysLogRow struct {
	Id       int64
	LogTime  int64
	LogLevel string
	LogMsg   string
}

func NewSysLog(db *sql.DB) *SysLog {
	return &SysLog{
		Model{
			db: db,
		},
	}
}

func (m *SysLog) Add(row *SysLogRow) (int64, error) {
	if row.LogMsg == "" {
		return 0, errors.New("日志内容不能为空")
	}
	if row.LogTime <= 0 {
		row.LogTime = time.Now().Unix()
	}
	ret, err := m.db.Exec("INSERT INTO syslog(log_time,log_level,log_msg) VALUES(?,?,?)", row.LogTime, row.LogLevel, row.LogMsg)
	if err != nil {
		return 0, err
	} else {
		return ret.LastInsertId()
	}
}

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

func (m *SysLog) Count() (int64, error) {
	var cnt int64
	row := m.db.QueryRow("SELECT COUNT(*) FROM syslog")
	if err := row.Scan(&cnt); err != nil {
		return 0, err
	} else {
		return cnt, nil
	}
}

func (m *SysLog) GetList(offset int64, limit int64, orderDesc bool) ([]*SysLogRow, error) {
	var (
		orderDir string
		ret      *sql.Rows
		err      error
	)
	if orderDesc {
		orderDir = "DESC"
	} else {
		orderDir = "ASC"
	}
	if limit > 0 {
		sql := fmt.Sprintf("SELECT id,log_time,log_level,log_msg FROM syslog ORDER BY id %s LIMIT ?,?", orderDir)
		ret, err = m.db.Query(sql, offset, limit)
	} else {
		sql := fmt.Sprintf("SELECT id,log_time,log_level,log_msg FROM syslog ORDER BY id %s", orderDir)
		ret, err = m.db.Query(sql)
	}
	if err != nil {
		return nil, err
	} else {
		rows := make([]*SysLogRow, 0)
		for ret.Next() {
			row := SysLogRow{}
			err = ret.Scan(&row.Id, &row.LogTime, &row.LogLevel, &row.LogMsg)
			if err != nil {
				continue
			}
			rows = append(rows, &row)
		}
		return rows, nil
	}
}
