package entity

import (
	"bytes"
	"database/sql"

	"github.com/jinzhu/gorm"
)

type OperationLogQuery struct {
	StartTimeInSec int64
	EndTimeInSec   int64
	ManagementType string
	OperationType  string
	From           int
	Size           int
	OrderBy        string
	Desc           bool
}

func GetAllOperationEvents(db *gorm.DB, query *OperationLogQuery) ([]OperateEvent, int64, error) {
	where, values := buildQuery(query)
	var operationLogs []OperateEvent
	var total int64
	db = db.Table("operate_event").Where(where, values...).Count(&total).Limit(query.Size).Offset(query.From).Order(query.OrderBy, query.Desc).Find(&operationLogs)
	return operationLogs, total, db.Error
}

type OperationEventScanResult struct {
	rows *sql.Rows
}

func (scan *OperationEventScanResult) Next() bool {
	return scan.rows.Next()
}

func (scan *OperationEventScanResult) Close() error {
	return scan.rows.Close()
}

func (scan *OperationEventScanResult) Get() (*OperateEvent, error) {
	event := OperateEvent{}
	err := scan.rows.Scan(&event.ID, &event.ManagementType, &event.OperationType, &event.User, &event.OperationTime, &event.Content, &event.Result, &event.Cost)
	return &event, err
}

func ScanOperationEvents(db *gorm.DB, query *OperationLogQuery) (*OperationEventScanResult, error) {
	where, values := buildQuery(query)
	rows, err := db.DB().Query("select id, management_type, operation_type, user_id,  operation_time, content, result, cost_time from operate_event where "+where, values...)
	return &OperationEventScanResult{rows: rows}, err
}

func buildQuery(query *OperationLogQuery) (string, []interface{}) {
	var values []interface{}
	where := bytes.Buffer{}
	where.WriteString(" 1=1  ")
	if query.ManagementType != "" {
		where.WriteString(" and management_type=? ")
		values = append(values, query.ManagementType)
	}
	if query.OperationType != "" {
		where.WriteString(" and operation_type=? ")
		values = append(values, query.OperationType)
	}
	if query.StartTimeInSec > 0 {
		where.WriteString(" and operation_time >= ? ")
		values = append(values, query.StartTimeInSec)
	}
	if query.StartTimeInSec > 0 {
		where.WriteString(" and operation_time <= ? ")
		values = append(values, query.EndTimeInSec)
	}
	return where.String(), values
}
