package common

import (
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"

	_const "github.com/pingcap-inc/clinic/pkg/const"
	"github.com/pingcap-inc/clinic/pkg/db"
)

type PaginationQuery struct {
	Page  int `json:"page"`
	Limit int `json:"limit"`

	// the filed indicate whether the limit is raw value
	RawLimit bool
}

type SuccessResp struct {
	Status string `json:"status"`
}

func SuccessResponse() SuccessResp {
	return SuccessResp{
		Status: "ok",
	}
}

type Rebuild struct {
	DataType int `json:"dataType"`

	ItemID string `json:"itemID"`

	HealthReport          bool   `json:"healthReport"`          // if build health report
	HealthReportStartUnix uint64 `json:"healthReportStartUnix"` // only used when health report is for cluster under cloud org
	HealthReportEndUnix   uint64 `json:"healthReportEndUnix"`   // only used when health report is for cluster under cloud org
	OrgType               string `json:"orgType"`
	ClusterID             string `json:"clusterID"`
	OrgID                 uint   `json:"orgID"`
}

type Pair struct {
	Key   string
	Value string
}

type PairInt struct {
	Key   string
	Value int
}

type PreCreateResponse struct {
	Partseq    int   `json:"sequence"`
	BlockBytes int64 `json:"blockbytes"`
}

type FlushResponse struct {
	ResultURL string `json:"result"`
}

type TaskStatusResp struct {
	Items []TaskStatus `json:"items"`
}

type TaskStatus struct {
	ItemID    string `json:"itemID"`
	Status    int    `json:"status"`
	StartTime int64  `json:"startTime"`
	EndTime   int64  `json:"endTime"`
	TaskType  int    `json:"taskType"`
}

type APIDataType int

const (
	UnsupportTask APIDataType = iota
	MetricTask
	LogTask
	SlowLogTask
	RebuildConfTask
)

func (t APIDataType) Validate() bool {
	return t <= RebuildConfTask && t > UnsupportTask
}

func ConverToTaskType(t APIDataType) _const.TaskType {
	if t == SlowLogTask {
		return _const.TaskType(LogTask)
	}

	return _const.TaskType(t)
}

type Comparison struct {
	Creator   string           `json:"creator"`
	ClusterID string           `json:"clusterID"`
	OrgID     uint             `json:"org_id"`
	OrgType   string           `json:"orgType"`
	Args      db.ComparisonArg `json:"args"`
}

// todo@toto maybe only need hash time range
func Hash(args db.ComparisonArg) (string, error) {
	key := db.ComparisonArg{
		StartTime1: args.StartTime1,
		EndTime1:   args.EndTime1,
		StartTime2: args.StartTime2,
		EndTime2:   args.EndTime2,
	}
	data, err := json.Marshal(key)
	if err != nil {
		return "", err
	}
	m := sha256.New()
	m.Write(data)
	return hex.EncodeToString(m.Sum(nil)), nil
}

type TaskReponse struct {
	ID uint `json:"id"`
}
