package upload

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"testing"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"github.com/onsi/gomega"
	"github.com/pingcap/diag/pkg/crypto"

	"github.com/pingcap-inc/clinic/pkg/api/env"
	"github.com/pingcap-inc/clinic/pkg/auth/session"
	"github.com/pingcap-inc/clinic/pkg/db"
	"github.com/pingcap-inc/clinic/pkg/db/model"
	"github.com/pingcap-inc/clinic/pkg/resource_limit"
)

func TestCanUpload(t *testing.T) {
	limiter := resource_limit.NewQuotaLimiter()
	g := gomega.NewGomegaWithT(t)
	u := &session.CtxUser{
		OrgIDInApiToken: 1,
		Internal:        false,
	}
	for i := 0; i < 20; i++ {
		ok, reason := canUpload(fmt.Sprintf("TestCanUpload%d", i), 3221225472, u, limiter)
		if !ok {
			t.Log(reason)
		}
		if i < 10 {
			g.Expect(ok).To(gomega.BeTrue())
		} else {
			g.Expect(ok).To(gomega.BeFalse())
		}

		if ok {
			_, err := model.AddClusterIfPresent(&db.Cluster{
				ClusterID: fmt.Sprintf("TestCanUpload%d", i),
				OrgID:     1,
			})

			g.Expect(err).To(gomega.Succeed())
		}
	}

	u.Internal = true
	for i := 10; i < 20; i++ {
		ok, _ := canUpload(fmt.Sprintf("TestCanUpload%d", i), 9000000000, u, limiter)
		g.Expect(ok).To(gomega.BeTrue())
	}
}

func TestPrecreate(t *testing.T) {
	g := gomega.NewWithT(t)
	reqMap := map[string]any{
		"cluster_id":   "Test_01_1",
		"cluster_type": "tidb-cluster",
		"ext":          "To boldly go where no one has gone before",
	}
	body, err := json.Marshal(reqMap)
	if err != nil {
		fmt.Println("TestPostReq json.Marshal err:", err)
		return
	}

	var w io.Writer
	metaBuf := new(bytes.Buffer)
	w, _ = crypto.NewEncryptWriter(&publicKey, metaBuf)
	_, err = w.Write(body)
	g.Expect(err).To(gomega.Succeed())

	params := []gin.Param{
		{
			Key:   "oid",
			Value: "1",
		},
		{
			Key:   "x-csrf-token",
			Value: "1111",
		},
		{
			Key:   "cid",
			Value: "Test_01_1",
		},
	}
	status := env.EnvironmentInit("POST", service.Precreate, params, metaBuf.Bytes(), "?uuid=\"c0bc9257-f444-4a4d-a7fd-5767bd7956ab\"&length=1000&filename=\"testfile\"", service.rbac, &service.cfg.SinkConfig.LogConfig)
	g.Expect(status).To(gomega.Equal(http.StatusOK))
}

func TestUUID(t *testing.T) {
	fmt.Println(uuid.New())
}
