package oldreport

import (
	"fmt"
	"os"
	"testing"
	"time"

	"github.com/pingcap-inc/clinic/pkg/auth/session"
	"github.com/pingcap-inc/clinic/pkg/datasource"

	"github.com/pingcap/log"
	"go.uber.org/zap"

	"github.com/pingcap-inc/clinic/pkg/config"
	"github.com/pingcap-inc/clinic/pkg/db"
	model2 "github.com/pingcap-inc/clinic/pkg/db/model"
	"github.com/pingcap-inc/clinic/pkg/db_docker"
	"github.com/pingcap-inc/clinic/pkg/db_docker/db/impl"
	"github.com/pingcap-inc/clinic/pkg/rbac"
)

func TestMain(m *testing.M) {
	fmt.Println("start tests")
	impl.ReleaseAll()
	_ = db_docker.TryInitDB()
	initService()
	initData(service.rbac)
	initUploadFile(&testing.T{})
	code := m.Run()
	impl.ReleaseAll()
	os.Exit(code)
}

func initService() {
	service.rbac = initAuth()
}

func initAuth() *rbac.AuthCasbin {
	cfg := &config.Config{
		DBConfig: &config.DBConfig{
			User:     "root", // centralDockerDB.User,
			Host:     db_docker.DockerDB.Host,
			Port:     db_docker.DockerDB.Port,
			Password: db_docker.DockerDB.Password,
			Database: "unittest",
		},
	}
	auth, err := rbac.InitAuth(cfg.DBConfig, "../../../rbac_model")
	if err != nil {
		panic(err)
	}
	return auth
}

func initData(rbac *rbac.AuthCasbin) {
	policyCnt := len(rbac.GetEnforcer().GetPolicy())
	_, err := model2.CreateOrganization("pingcap-inc", "create for test", 1, func(orgID uint) error {
		var err error
		if err = rbac.InitOrgRBAC(orgID); err != nil {
			log.Error("apply rbac for org failed", zap.Uint("org", orgID), zap.Error(err))
			return err
		}
		return err
	})
	if err != nil {
		panic(err)
	}
	err = rbac.AttachRoleForUser(1, 1, uint(policyCnt+1))
	if err != nil {
		panic(err)
	}
	err = rbac.AttachRoleForUser(2, 2, uint(policyCnt+2))
	if err != nil {
		panic(err)
	}

	if _, err = datasource.GetOrganization(&session.CtxUser{}, 1); err != nil {
		panic(err)
	}

	if _, err = model2.InsertUserIfAbsent("internal_test", "test_user01", "test01", true); err != nil {
		panic(err)
	}
	for i := 0; i < 10; i++ {
		cid := fmt.Sprintf("Test_01_%d", i)
		name := fmt.Sprintf("test01_%d", i)
		startTime, err := time.Parse("2006-01-02 15:04:05", "2017-04-11 13:0"+fmt.Sprint(i)+":37")
		if err != nil {
			panic(err)
		}
		endTime, err := time.Parse("2006-01-02 15:04:05", "2017-04-12 13:0"+fmt.Sprint(i)+":37")
		if err != nil {
			panic(err)
		}
		_, err = model2.AddClusterIfPresent(&db.Cluster{
			ClusterID:   cid,
			Name:        name,
			OrgID:       uint(1),
			StartTime:   uint64(startTime.Unix()),
			EndTime:     uint64(endTime.Unix()),
			Version:     "v5.1.0",
			ClusterType: "1",
		})
		if err != nil {
			panic(err)
		}
	}

	for i := 0; i < 10; i++ {
		cid := fmt.Sprintf("Test_02_%d", i)
		name := fmt.Sprintf("test02_%d", i)
		_, err = model2.AddClusterIfPresent(&db.Cluster{
			ClusterID: cid,
			Name:      name,
			OrgID:     uint(2),
			Version:   "v5.2.0",
		})
		if err != nil {
			panic(err)
		}
	}
	for i := 0; i < 10; i++ {
		startTime, _ := time.Parse("2006-01-02 15:04:05", "2017-04-11 13:0"+fmt.Sprint(i)+":37")
		endTime, _ := time.Parse("2006-01-02 15:04:05", "2017-04-12 13:0"+fmt.Sprint(i)+":37")
		file := db.UploadFile{
			ClusterID: "Test_01_1",
			OrgID:     1,
			BeginTime: &startTime,
			EndTime:   &endTime,
			FileUUID:  fmt.Sprintf("FileUUID_%d", i),
		}
		err = model2.InsertUploadFile(&file)
	}
	/*fileconfig := config.FileStorage{}
	awss, _ := aws.NewAWSStorage(fileconfig)
	manager := manager2.NewUploadFileManager(awss)*/
	if err != nil {
		panic(err)
	}
}

func initUploadFile(t *testing.T) {
	clusterID := "123"

	loc, _ := time.LoadLocation("Asia/Shanghai")
	beginTime, _ := time.ParseInLocation("2006-01-02 15:04:05", "2018-07-11 15:07:51", loc)
	endTime, _ := time.ParseInLocation("2006-01-02 15:04:05", "2018-07-10 15:07:51", loc)
	uf1 := &db.UploadFile{
		FileUUID:         "Test_Join1",
		FileOriginalName: "Test_Join1",
		Alias:            "Test_Join1",
		StorageType:      string(config.AWSStorageType),
		UploadID:         "Test_Join1",
		ClusterID:        clusterID,
		BeginTime:        formatTime(beginTime.Add(time.Duration(2) * time.Hour)),
		EndTime:          formatTime(endTime.Add(time.Duration(-2) * time.Hour)),
		OrgID:            1111,
		FileLen:          4096,
	}
	report1 := &db.HealthReport{
		ReportUUID: "Test_Join1",
		FileUUID:   "Test_Join1",
		Status:     "running",
	}

	uf2 := &db.UploadFile{
		FileUUID:         "Test_Join2",
		FileOriginalName: "Test_Join2",
		Alias:            "Test_Join2",
		StorageType:      string(config.AWSStorageType),
		UploadID:         "Test_Join2",
		ClusterID:        clusterID,
		BeginTime:        formatTime(beginTime.Add(time.Duration(-2) * time.Hour)),
		EndTime:          formatTime(endTime.Add(time.Duration(2) * time.Hour)),
		OrgID:            1111,
		FileLen:          4096,
	}
	report2 := &db.HealthReport{
		ReportUUID: "Test_Join2",
		FileUUID:   "Test_Join2",
		Status:     "success",
	}

	uf3 := &db.UploadFile{
		FileUUID:         "Test_Join3",
		FileOriginalName: "Test_Join3",
		Alias:            "Test_Join3",
		StorageType:      string(config.AWSStorageType),
		UploadID:         "Test_Join3",
		ClusterID:        clusterID,
		BeginTime:        formatTime(beginTime.Add(time.Duration(2) * time.Hour)),
		EndTime:          formatTime(endTime.Add(time.Duration(-2) * time.Hour)),
		OrgID:            1111,
		FileLen:          4096,
	}

	if err := model2.InsertUploadFile(uf1); err != nil {
		t.Error("insertUpload file failed", err)
		return
	}
	if err := model2.InsertUploadFile(uf2); err != nil {
		t.Error("insertUpload file failed", err)
		return
	}
	if err := model2.InsertUploadFile(uf3); err != nil {
		t.Error("insertUpload file failed", err)
		return
	}

	if err := model2.InsertOrUpdateReport(report1); err != nil {
		t.Error("insert report", err)
		return
	}
	if err := model2.InsertOrUpdateReport(report2); err != nil {
		t.Error("insert report", err)
		return
	}
}

func formatTime(t time.Time) *time.Time {
	return &t
}
