package core

import (
	"fmt"
	"sort"

	"github.com/ngaut/log"
	"github.com/pingcap/schrodinger/config"
	"github.com/pingcap/schrodinger/pkg/test_client"
	"github.com/pingcap/schrodinger/pkg/types"
)

func genPodInfo(pods []types.PodStatus, typeName string) []*client.PodInfo {
	var podInfos []*client.PodInfo

	for _, p := range pods {
		info := &client.PodInfo{
			Name:        p.Name,
			IP:          p.PodIP,
			AgentPort:   config.GetGlobalConfig().Cat.AgentPort,
			NodeIP:      p.NodeIP,
			ContainerID: p.ContainerID,
		}

		switch typeName {
		case client.TiDB:
			info.ServicePort = config.GetGlobalConfig().Cat.TidbServicePort
		case client.PD:
			info.ServicePort = config.GetGlobalConfig().Cat.PdServicePort
			info.PdDataDir = config.GetGlobalConfig().Cat.PdDataDir
			info.DataDir = config.GetGlobalConfig().Cat.PdDataDir
		case client.TiKV:
			info.ServicePort = config.GetGlobalConfig().Cat.TikvServicePort
			info.TikvDataDir = config.GetGlobalConfig().Cat.TikvDataDir
			info.DataDir = config.GetGlobalConfig().Cat.TikvDataDir
		default:
			log.Errorf("type %s is not valid", typeName)
			continue
		}

		podInfos = append(podInfos, info)
	}

	return podInfos
}

func genCatNamespace(config *types.Cat) string {
	return fmt.Sprintf("%s-tidb-cluster", config.Name)
}

func int64InSlice(a int64, list []int64) bool {
	for _, b := range list {
		if b == a {
			return true
		}
	}
	return false
}

func getBrief(experiment *types.ExperimentProcess) *ExperimentBrief {
	var catState types.CatState
	if experiment.Cat == nil {
		catState = types.CatStateNormal
	} else {
		catState = experiment.Cat.State
	}
	return &ExperimentBrief{
		ID:         experiment.ID,
		Ctime:      experiment.Ctime,
		State:      experiment.State,
		Stage:      experiment.Stage,
		CatState:   catState,
		Author:     experiment.Author,
		Annotation: experiment.Annotation,
		Destroyed:  experiment.Destroyed,
	}
}

func getBoxSummary(box *types.Box, experimentSummary map[int64]ExperimentBriefs, resourceOccupation map[int64]bool, hasPending map[int64]bool) *Summary {
	occupation, exist := resourceOccupation[box.ID]
	if !exist {
		occupation = false
	}
	pending, exist := hasPending[box.ID]
	if !exist {
		pending = false
	}

	experiments := experimentSummary[box.ID]
	sort.Sort(experiments)
	if len(experiments) > 10 {
		experiments = experiments[len(experiments)-10:]
	}
	return &Summary{
		Experiments:        experiments,
		ResourceOccupation: occupation,
		TestInOrder:        box.Tests.InOrder,
		HasPending:         pending,
	}
}
