package main

import (
	"encoding/json"
	"flag"
	"os"

	. "github.com/pingcap/test-infra/common/model"
	"github.com/pingcap/test-infra/services/tps/pkg/schedule"

	"github.com/argoproj/argo-workflows/v3/pkg/apis/workflow"
	wf "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"sigs.k8s.io/yaml"
)

type Input struct {
	Entry PlanRef    `json:"entry"`
	Cases []TestCase `json:"cases"`
	Plans []TestPlan `json:"plans"`
}

func main() {
	var input Input
	var opts struct {
		genName string
		input   string
		output  string

		serviceAccountName    string
		artifactRepositoryRef string

		endpointRMS  string
		endpointTCMS string
	}
	flag.StringVar(&opts.genName, "n", "plan-exec-", "generate name")
	flag.StringVar(&opts.input, "i", "", "input file")
	flag.StringVar(&opts.output, "o", "", "output file")
	flag.StringVar(&opts.serviceAccountName, "s", "", "service account name")
	flag.StringVar(&opts.artifactRepositoryRef, "a", "", "artifact repository ref")
	flag.StringVar(&opts.endpointRMS, "rms", "http://rms.test-infra", "rms endpoint")
	flag.StringVar(&opts.endpointTCMS, "tcms", "http://tcms.test-infra", "tcms endpoint")
	flag.Parse()

	inputFile := os.Stdin
	if len(opts.input) > 0 {
		f, err := os.Open(opts.input)
		if err != nil {
			panic(err)
		}
		defer f.Close()
		inputFile = f
	}
	outputFile := os.Stdout
	if len(opts.output) > 0 {
		f, err := os.OpenFile(opts.output, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
		if err != nil {
			panic(err)
		}
		defer f.Close()
		outputFile = f
	}

	if err := json.NewDecoder(inputFile).Decode(&input); err != nil {
		panic(err)
	}

	cc := schedule.NewMockContext(input.Cases, input.Plans, 0)
	wfSpec, err := schedule.CompileArgo(cc, input.Entry)
	if err != nil {
		panic(err)
	}
	if len(opts.serviceAccountName) > 0 {
		wfSpec.ServiceAccountName = opts.serviceAccountName
	}
	if len(opts.artifactRepositoryRef) > 0 {
		ref := new(wf.ArtifactRepositoryRef)
		err = json.Unmarshal([]byte(opts.artifactRepositoryRef), ref)
		if err != nil {
			panic(err)
		}
		wfSpec.ArtifactRepositoryRef = ref
	}

	out, err := yaml.Marshal(wf.Workflow{
		TypeMeta: metav1.TypeMeta{
			Kind:       workflow.WorkflowKind,
			APIVersion: workflow.APIVersion,
		},
		ObjectMeta: metav1.ObjectMeta{
			GenerateName: opts.genName,
		},
		Spec: *wfSpec,
	})
	if err != nil {
		panic(err)
	}
	outputFile.Write(out)
}
