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"
)

const (
	poll = 2 * time.Second
)

func (f *Framework) CreateBR(testbed *k8s.Testbed) *k8s.BR {
	client := k8s.NewBRClient(f.KubeClientSetPack)

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

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

func (f *Framework) GetBR(handle apiresource.ResourceHandle) *k8s.BR {
	client := k8s.NewBRClient(f.KubeClientSetPack)
	r, err := client.Get(handle)
	ExpectNoError(err)
	return r.(*k8s.BR)
}

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

func (f *Framework) DeleteBRWaited(br *k8s.BR) {
	client := k8s.NewBRClient(f.KubeClientSetPack)
	ExpectNoError(client.Delete(br.ResourceHandle))

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

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