package model

import (
	"fmt"
	"testing"

	"github.com/onsi/gomega"

	"github.com/pingcap-inc/clinic/pkg/config"
	"github.com/pingcap-inc/clinic/pkg/db"
)

func Test_UpsertFileUploadPart(t *testing.T) {
	fileUUID := "Test_UpsertFileUploadPart"

	g := gomega.NewGomegaWithT(t)

	uf := &db.UploadFile{
		FileUUID:         fileUUID,
		FileOriginalName: "1",
		Alias:            "",
		StorageType:      string(config.AWSStorageType),
		UploadID:         "Test_QueryMaxFileUploadedPartRareCase",
		ClusterID:        "1",
	}
	err := InsertUploadFile(uf)
	g.Expect(err).To(gomega.Succeed())

	err = UpsertUploadFilePart(fileUUID, 1, "007f917558e0c343d8adfaa44bdfa95c", 1)

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

	err = UpsertUploadFilePart(fileUUID, 1, "007f917558e0c343d8adfaa44bdfa95cduplicate", 1)
	g.Expect(err).To(gomega.Succeed())

	ufp, err := QueryUploadFilePart(fileUUID, 1)
	g.Expect(err).To(gomega.Succeed())

	g.Expect(ufp.Etag).To(gomega.Equal("007f917558e0c343d8adfaa44bdfa95cduplicate"))
}

func Test_QueryMaxFileUploadedPart(t *testing.T) {
	fileUUID := "Test_QueryMaxFileUploadedPart"

	g := gomega.NewGomegaWithT(t)

	uf := &db.UploadFile{
		FileUUID:         fileUUID,
		FileOriginalName: "1",
		Alias:            "",
		StorageType:      string(config.AWSStorageType),
		UploadID:         fileUUID,
		FileLen:          1,
	}
	err := InsertUploadFile(uf)
	g.Expect(err).To(gomega.Succeed())

	for i := 1; i < 20; i++ {
		err := UpsertUploadFilePart(fileUUID, i, "007f917558e0c343d8adfaa44bdfa95c", 1)
		g.Expect(err).To(gomega.Succeed())
	}

	ufp, err := QueryMaxFileUploadedPart(fileUUID)
	g.Expect(err).To(gomega.Succeed())
	g.Expect(ufp.SerialNumber).To(gomega.Equal(19))
}

func Test_QueryMaxFileFailed(t *testing.T) {
	fileUUID := "Test_QueryMaxFileUploadedPartFailed"

	g := gomega.NewGomegaWithT(t)

	err := UpsertUploadFilePart(fileUUID, 2, "007f917558e0c343d8adfaa44bdfa95c", 1)
	g.Expect(err).To(gomega.MatchError(fmt.Sprintf("the upload file record is not existed, file=%s", fileUUID)))
}

func Test_QueryMaxFileUploadedPartRareCase(t *testing.T) {
	fileUUID := "Test_QueryMaxFileUploadedPartRareCase"

	g := gomega.NewGomegaWithT(t)

	uf := &db.UploadFile{
		FileUUID:         fileUUID,
		FileOriginalName: "1",
		Alias:            "",
		StorageType:      string(config.AWSStorageType),
		UploadID:         "Test_QueryMaxFileUploadedPartRareCase",
		ClusterID:        "1",
	}
	err := InsertUploadFile(uf)
	g.Expect(err).To(gomega.Succeed())

	err = UpsertUploadFilePart(fileUUID, 2, "007f917558e0c343d8adfaa44bdfa95c", 1)
	g.Expect(err).To(gomega.Succeed())

	err = UpsertUploadFilePart(fileUUID, 1, "007f917558e0c343d8adfaa44bdfa95c", 1)
	g.Expect(err).To(gomega.Succeed())

	err = UpsertUploadFilePart(fileUUID, 3, "007f917558e0c343d8adfaa44bdfa95c", 1)
	g.Expect(err).To(gomega.Succeed())

	err = UpsertUploadFilePart(fileUUID, 5, "007f917558e0c343d8adfaa44bdfa95c", 1)
	g.Expect(err).To(gomega.Succeed())

	err = UpsertUploadFilePart(fileUUID, 6, "007f917558e0c343d8adfaa44bdfa95c", 1)
	g.Expect(err).To(gomega.Succeed())

	// serial 5 is existed
	ufp, err := QueryUploadFilePart(fileUUID, 5)
	g.Expect(err).To(gomega.Succeed())
	g.Expect(ufp.SerialNumber).To(gomega.Equal(5))

	// serial 6 is existed
	ufp, err = QueryUploadFilePart(fileUUID, 6)
	g.Expect(err).To(gomega.Succeed())
	g.Expect(ufp.SerialNumber).To(gomega.Equal(6))

	ufp, err = QueryMaxFileUploadedPart(fileUUID)
	g.Expect(err).To(gomega.Succeed())
	g.Expect(ufp.SerialNumber).To(gomega.Equal(3))
}

func Test_UpsertUploadPartCompleted(t *testing.T) {
	fileUUID := "Test_UpsertUploadPartCompleted"

	g := gomega.NewGomegaWithT(t)

	uf := &db.UploadFile{
		FileUUID:         fileUUID,
		FileOriginalName: "1",
		Alias:            "test",
		StorageType:      string(config.AWSStorageType),
		UploadID:         "Qb9fLCuWNCNsim713mWLmDd0RzpHqImRVqdYYBInvKOv5eyvdY..9iZHraFwcbGFL0Pkbr7cKpzwPKJMVaehP.GJ9WIwXUsOHcxwvJ99VE2jLKGPlLu3T13fJLfGygY5",
		ClusterID:        "1",
	}
	err := InsertUploadFile(uf)
	g.Expect(err).To(gomega.Succeed())

	err = UploadFileCompleted(fileUUID)
	g.Expect(err).To(gomega.Succeed())

	err = UpsertUploadFilePart(fileUUID, 1, "007f917558e0c343d8adfaa44bdfa95c", 1)
	g.Expect(err).To(gomega.MatchError(fmt.Sprintf("the file is completed, file=%s", fileUUID)))
}

func Test_QueryMaxFileUploadedPart2(t *testing.T) {
	fileUUID := "Test_QueryMaxFileUploadedPart2"

	g := gomega.NewGomegaWithT(t)

	uf := &db.UploadFile{
		FileUUID:         fileUUID,
		FileOriginalName: "1",
		Alias:            "",
		StorageType:      string(config.AWSStorageType),
		UploadID:         fileUUID,
		FileLen:          1,
	}
	err := InsertUploadFile(uf)
	g.Expect(err).To(gomega.Succeed())

	for i := 2; i <= 20; i++ {
		err := UpsertUploadFilePart(fileUUID, i, "007f917558e0c343d8ddsdfaa44bdfa95c", 1)
		g.Expect(err).To(gomega.Succeed())
	}

	ufp, err := QueryMaxFileUploadedPart(fileUUID)
	g.Expect(err).To(gomega.Succeed())
	g.Expect(ufp == nil).To(gomega.BeTrue())
}
