package experiment

import (
	"strings"
	"time"

	"github.com/pingcap/schrodinger/config"
	"github.com/pingcap/schrodinger/pkg/types"
	"github.com/pingcap/schrodinger/util"
)

func reportInformation(experiment *Experiment) *types.ExperimentReport {
	report := &types.ExperimentReport{
		Name:      experiment.name(),
		Namespace: experiment.getTestNamespace(),
		ID:        experiment.process.ID,
		BoxID:     experiment.process.BoxID,
		BoxIndex:  experiment.process.BoxIndex,
		Ctime:     experiment.process.Ctime,
		Utime:     time.Now().Format(util.TimeFormat),

		State:         experiment.process.State,
		Stage:         experiment.process.Stage,
		Destroyed:     experiment.process.Destroyed,
		StatusMessage: experiment.process.StatusMessage,

		Tests:            make([]*types.TestReport, 0),
		DetailLink:       util.GenExperimentLink(experiment.process.ID),
		BenchHistoryLink: util.GenBenchHistoryLink(experiment.process.BoxID),
	}

	if experiment.cat != nil {
		report.Config = experiment.cat.Config()
		report.RunVersion = experiment.cat.RunVersion()
		report.Cat = experiment.cat.Report()
	} else if experiment.process.Report != nil {
		report.Config = experiment.process.Report.Config
		report.RunVersion = experiment.process.Report.RunVersion
		report.Cat = experiment.process.Report.Cat
		report.Tests = experiment.process.Report.Tests
		report.TestResults = experiment.process.Report.TestResults
		return report
	}

	for _, t := range experiment.process.Tests {
		testReport := genTestReport(t.Name, experiment)
		if testReport != nil {
			report.Tests = append(report.Tests, testReport)
		}
	}

	if experiment.Type() == types.BoxTypeBench {
		report.TestResults = experiment.store.ListTestResultsByExperiment(experiment.process.ID)
	}

	return report
}

func genTestReport(name string, experiment *Experiment) *types.TestReport {
	testProc, exist := experiment.process.Tests[name]
	if !exist {
		return nil
	}

	report := &types.TestReport{
		ExperimentID: experiment.id(),
		Status:       testProc.Status,
		Ctime:        testProc.Ctime,
		Utime:        testProc.Utime,
		Name:         testProc.Name,
		Namespace:    testProc.Namespace,
	}

	t, exist := experiment.tests[name]
	if !exist {
		return report
	}

	if t.Proc.Pod == nil {
		return report
	}

	report.ProcStatus = t.ProcStatus().String()
	report.PodName = t.Proc.Pod.GetName()
	report.PodIP = t.Proc.Pod.Status.PodIP
	report.HostIP = t.Proc.Pod.Status.HostIP

	if t.IsError() {
		report.Log = t.GetLogs(config.GetGlobalConfig().Test.LogLines)
	}

	if len(t.Proc.Pod.Status.ContainerStatuses) > 0 {
		report.ContainerID = strings.TrimPrefix(t.Proc.Pod.Status.ContainerStatuses[0].ContainerID, "docker://")
		report.LogPath = util.GenLogURL(report.Namespace, report.PodName)
		testProc.Report = report
	}

	return report
}
