package tikv_cdc

import (
	"time"
)

// TODO: All structures in this file have corresponding counterparts in
// migration/cdc, maybe we can import them.

// Command `cli changefeed query` result
type ChangefeedMeta struct {
	Info       ChangeFeedInfo      `json:"info"`
	Status     ChangeFeedStatus    `json:"status"`
	Count      uint64              `json:"count"`
	TaskStatus []CaptureTaskStatus `json:"task-status"`
}

type ChangeFeedStatus struct {
	ResolvedTs   uint64 `json:"resolved-ts"`
	CheckpointTs uint64 `json:"checkpoint-ts"`
	AdminJobType int    `json:"admin-job-type"`
}

type ChangeFeedInfo struct {
	SinkURI      string            `json:"sink-uri"`
	Opts         map[string]string `json:"opts"`
	CreateTime   time.Time         `json:"create-time"`
	StartTs      uint64            `json:"start-ts"`
	TargetTs     uint64            `json:"target-ts"`
	AdminJobType int               `json:"admin-job-type"`
	Engine       string            `json:"sort-engine"`
	SortDir      string            `json:"sort-dir"`
	Config       ReplicaConfig     `json:"config"`
	State        string            `json:"state"`
	ErrorHis     []int64           `json:"history"`
	Error        *RunningError     `json:"error"`

	CreatorVersion string `json:"creator-version"`
}

type DispatchRule struct {
	Matcher    []string `toml:"matcher" json:"matcher"`
	Dispatcher string   `toml:"dispatcher" json:"dispatcher"`
}

type ColumnSelector struct {
	Matcher []string `toml:"matcher" json:"matcher"`
	Columns []string `toml:"columns" json:"columns"`
}

type SinkConfig struct {
	DispatchRules   []*DispatchRule   `toml:"dispatchers" json:"dispatchers"`
	Protocol        string            `toml:"protocol" json:"protocol"`
	ColumnSelectors []*ColumnSelector `toml:"column-selectors" json:"column-selectors"`
}

type ReplicaConfig struct {
	EnableOldValue   bool             `toml:"enable-old-value" json:"enable-old-value"`
	CheckGCSafePoint bool             `toml:"check-gc-safe-point" json:"check-gc-safe-point"`
	Sink             *SinkConfig      `toml:"sink" json:"sink"`
	Scheduler        *SchedulerConfig `toml:"scheduler" json:"scheduler"`
}

type SchedulerConfig struct {
	Tp          string `toml:"type" json:"type"`
	PollingTime int    `toml:"polling-time" json:"polling-time"`
}

type CaptureTaskStatus struct {
	CaptureID  string      `json:"capture-id"`
	TaskStatus *TaskStatus `json:"status"`
}

// Command `cli changefeed list` result
type RunningError struct {
	Addr    string `json:"addr"`
	Code    string `json:"code"`
	Message string `json:"message"`
}

type ChangefeedResp struct {
	FeedState    string        `json:"state"`
	TSO          uint64        `json:"tso"`
	Checkpoint   string        `json:"checkpoint"`
	RunningError *RunningError `json:"error"`
}

type ChangefeedCommonInfo struct {
	ID      string          `json:"id"`
	Summary *ChangefeedResp `json:"summary"`
}

// Command `cli changefeed statistics` result
type StatisticsInfo struct {
	OPS            uint64 `json:"ops"`
	Count          uint64 `json:"count"`
	SinkGap        string `json:"sink_gap"`
	ReplicationGap string `json:"replication_gap"`
}

// Command `cli capture list` result
type CaptureInfo struct {
	ID      string `json:"id"`
	IsOwner bool   `json:"is-owner"`
	Address string `json:"address"`
}

// Command `cli processor list` result
type ProcessorInfo struct {
	ChangefeedId string `json:"changefeed_id"`
	CaptureId    string `json:"capture_id"`
}

// Command `cli processor query` result
type KeySpanInfo struct {
	StartTs uint64 `json:"start-ts"`
	Start   []byte `json:"start"`
	End     []byte `json:"end"`
}

type KeySpanOperation struct {
	Delete          bool              `json:"delete"`
	Flag            uint64            `json:"flag,omitempty"`
	BoundaryTs      uint64            `json:"boundary_ts"`
	Status          uint64            `json:"status,omitempty"`
	RelatedKeySpans []KeySpanLocation `json:"related_key_spans"`
}

type KeySpanLocation struct {
	CaptureID string `json:"capture_id"`
	KeySpanID uint64 `json:"keyspan_id"`
}

type TaskStatus struct {
	KeySpans     map[uint64]*KeySpanInfo      `json:"keyspans"`
	Operation    map[uint64]*KeySpanOperation `json:"operation"`
	AdminJobType int                          `json:"admin-job-type"`
	ModRevision  int64                        `json:"-"`
}

type TaskPosition struct {
	CheckPointTs uint64        `json:"checkpoint-ts"`
	ResolvedTs   uint64        `json:"resolved-ts"`
	Count        uint64        `json:"count"`
	Error        *RunningError `json:"error"`
}

type ProcessorMeta struct {
	Status   *TaskStatus   `json:"status"`
	Position *TaskPosition `json:"position"`
}
