package framework

import (
	"fmt"
	"time"

	"k8s.io/apimachinery/pkg/util/wait"

	apiresource "github.com/pingcap/test-infra/common/model/resource"
	"github.com/pingcap/test-infra/sdk/resource"
	"github.com/pingcap/test-infra/sdk/resource/impl/k8s"
)

func (f *Framework) CreateLightning(testbed *k8s.Testbed) *k8s.TiDBLightning {
	client := k8s.NewLightningClient(f.KubeClientSetPack)

	r, err := client.Create([]byte(fmt.Sprintf(`{
    "name": "tidb-lightning",
    "testbed": "%s",
    "type": "%s",
    "spec": {
        "image": "docker.io/pingcap/tidb-lightning:v5.0.1",
        "resources": {
            "requests": {
                "memory": "64Mi",
                "cpu": "250m",
                "storage": "1Gi"
            }
        },
        "artifact": {
            "artifactPaths": ["/tmp/lightning.log*"]
        }
    }
}
`, testbed.Name, apiresource.ResourceTypeTiDBLightning)))

	ExpectNoError(err)
	return r.(*k8s.TiDBLightning)
}

func (f *Framework) CreateLightningWithQos(testbed *k8s.Testbed) *k8s.TiDBLightning {
	client := k8s.NewLightningClient(f.KubeClientSetPack)
	ExpectEqual(len(testbed.Qos) > 0, true, "Should In Testbed with qos")

	r, err := client.Create([]byte(fmt.Sprintf(`{
    "name": "tidb-lightning",
    "testbed": "%s",
    "type": "%s",
    "spec": {
        "image": "docker.io/pingcap/tidb-lightning:v5.0.1",
        "resources": {
            "requests": {
                "memory": "64Mi",
                "cpu": "250m",
                "storage": "1Gi"
            }
        }
    },
	"qos": {
		"podGroup":"%s"
	}
}
`, testbed.Name, apiresource.ResourceTypeTiDBLightning, testbed.Qos[0].PodGroup)))

	ExpectNoError(err)
	return r.(*k8s.TiDBLightning)
}

func (f *Framework) GetLightning(handle apiresource.ResourceHandle) *k8s.TiDBLightning {
	client := k8s.NewLightningClient(f.KubeClientSetPack)
	r, err := client.Get(handle)
	ExpectNoError(err)
	return r.(*k8s.TiDBLightning)
}

func (f *Framework) ArchiveLightning(handle apiresource.ResourceHandle, archiver resource.ArchiverFunc) {
	client := k8s.NewLightningClient(f.KubeClientSetPack)
	_, err := client.Artifact(handle, apiresource.GcArtifactAction{Log: true}, archiver)
	ExpectNoError(err)
}

func (f *Framework) DeleteLightningWaited(lightning *k8s.TiDBLightning) {
	client := k8s.NewLightningClient(f.KubeClientSetPack)
	ExpectNoError(client.Delete(lightning.ResourceHandle))

	err := wait.PollImmediate(poll, f.DeletionTimeout, func() (done bool, err error) {
		_, err = client.Get(lightning.ResourceHandle)
		if resource.IsResourceNotFoundError(err) {
			return true, nil
		}
		return false, nil
	})
	ExpectNoError(err)
}

func (f *Framework) WaitForLightningReady(lightning *k8s.TiDBLightning, timeout time.Duration) error {
	if err := wait.PollImmediate(poll, timeout, func() (done bool, err error) {
		if err := lightning.Sync(); err != nil {
			return false, err
		}
		return lightning.Ready(), nil
	}); err != nil {
		return fmt.Errorf("wait for lightning ready occur an error: %v", err)
	}
	return nil
}
