package tenant

import (
	"context"
	"testing"

	. "github.com/smartystreets/goconvey/convey"
	"github.com/tidbcloud/account/commons/config"
	"github.com/tidbcloud/account/idl/pbgen/proto/central"
	"github.com/tidbcloud/pkgv2/util"
)

func TestValidateRegistrationReq(t *testing.T) {
	ctx := context.Background()
	Convey("Google SSO", t, func() {
		req := &central.RegistrationReq{
			Country:                   "CN",
			FirstName:                 "",
			LastName:                  "",
			Email:                     "",
			Job:                       "",
			Company:                   "TEST",
			PhoneNumber:               "11111111111",
			Password:                  "",
			AcceptService:             true,
			RecaptchaResponse:         "",
			ThirdPartyAccountProvider: "",
			ThirdPartyAccountToken:    "",
			ConnectionType:            central.RegistrationReq_GOOGLE,
			Auth0Token:                "xxxx",
		}

		Convey("should be ok if all is well", func() {
			err := validateRegistrationReq(ctx, req, config.Auth0SocialConnectionGithub)
			So(err, ShouldBeNil)
		})

		Convey("should be ok if Company field is empty", func() {
			req.Company = ""
			err := validateRegistrationReq(ctx, req, config.Auth0SocialConnectionGithub)
			So(err, ShouldBeNil)
		})

		Convey("should be ok if PhoneNumber field is empty", func() {
			req.PhoneNumber = ""
			err := validateRegistrationReq(ctx, req, config.Auth0SocialConnectionGithub)
			So(err, ShouldBeNil)
		})

		Convey("should return error if auth0Token is empty", func() {
			req.Auth0Token = ""

			err := validateRegistrationReq(ctx, req, config.Auth0SocialConnectionGithub)
			So(err, ShouldNotBeNil)
		})

		Convey("should not return error if Country field is not empty", func() {
			err := validateRegistrationReq(ctx, req, config.Auth0SocialConnectionGithub)
			So(err, ShouldBeNil)
		})

		Convey("should not return error if Country field is empty", func() {
			req.Country = ""

			err := validateRegistrationReq(ctx, req, config.Auth0SocialConnectionGithub)
			So(err, ShouldBeNil)
		})
	})

	Convey("Github SSO", t, func() {
		req := &central.RegistrationReq{
			Country:                   "CN",
			FirstName:                 "",
			LastName:                  "",
			Email:                     "",
			Job:                       "",
			Company:                   "TEST",
			PhoneNumber:               "11111111111",
			Password:                  "",
			AcceptService:             true,
			RecaptchaResponse:         "",
			ThirdPartyAccountProvider: "",
			ThirdPartyAccountToken:    "",
			ConnectionType:            central.RegistrationReq_GITHUB,
			Auth0Token:                "xxxx",
		}

		Convey("should be ok if all is well", func() {
			err := validateRegistrationReq(ctx, req, config.Auth0SocialConnectionGithub)
			So(err, ShouldBeNil)
		})

		Convey("should be ok if Company field is empty", func() {
			req.Company = ""
			err := validateRegistrationReq(ctx, req, config.Auth0SocialConnectionGithub)
			So(err, ShouldBeNil)
		})

		Convey("should be ok if PhoneNumber field is empty", func() {
			req.PhoneNumber = ""
			err := validateRegistrationReq(ctx, req, config.Auth0SocialConnectionGithub)
			So(err, ShouldBeNil)
		})

		Convey("should return error if auth0Token is empty", func() {
			req.Auth0Token = ""

			err := validateRegistrationReq(ctx, req, config.Auth0SocialConnectionGithub)
			So(err, ShouldNotBeNil)
		})

		Convey("should not return error if Country field is not empty", func() {
			err := validateRegistrationReq(ctx, req, config.Auth0SocialConnectionGithub)
			So(err, ShouldBeNil)
		})

		Convey("should not return error if Country field is empty", func() {
			req.Country = ""

			err := validateRegistrationReq(ctx, req, config.Auth0SocialConnectionGithub)
			So(err, ShouldBeNil)
		})
	})

	Convey("Email Password Registration", t, func() {
		req := &central.RegistrationReq{
			Country:                   "CN",
			FirstName:                 "aaa",
			LastName:                  "bbb",
			Email:                     "test@pingcap.com",
			Job:                       "",
			Company:                   "TEST",
			PhoneNumber:               "11111111111",
			Password:                  "xxxxxxxx",
			AcceptService:             true,
			RecaptchaResponse:         "",
			ThirdPartyAccountProvider: "",
			ThirdPartyAccountToken:    "",
			ConnectionType:            central.RegistrationReq_EMAIL,
			Auth0Token:                "xxxx",
		}

		Convey("should be ok if all is well", func() {
			err := validateRegistrationReq(ctx, req, config.Auth0DatabaseConnection)
			So(err, ShouldBeNil)
		})

		Convey("should be ok if Company field is empty", func() {
			req.Company = ""
			err := validateRegistrationReq(ctx, req, config.Auth0DatabaseConnection)
			So(err, ShouldBeNil)
		})

		Convey("should be ok if PhoneNumber field is empty", func() {
			req.PhoneNumber = ""
			err := validateRegistrationReq(ctx, req, config.Auth0DatabaseConnection)
			So(err, ShouldBeNil)
		})

		Convey("should return error if Email is empty", func() {
			req.Email = ""

			err := validateRegistrationReq(ctx, req, config.Auth0DatabaseConnection)
			So(err, ShouldNotBeNil)
		})

		Convey("should return error if FirstName is empty", func() {
			req.FirstName = ""

			err := validateRegistrationReq(ctx, req, config.Auth0DatabaseConnection)
			So(err, ShouldNotBeNil)
		})

		Convey("should return error if LastName is empty", func() {
			req.LastName = ""

			err := validateRegistrationReq(ctx, req, config.Auth0DatabaseConnection)
			So(err, ShouldNotBeNil)
		})

		Convey("should not return error if Country field is not empty", func() {
			err := validateRegistrationReq(ctx, req, config.Auth0DatabaseConnection)
			So(err, ShouldBeNil)
		})

		Convey("should not return error if Country field is empty", func() {
			req.Country = ""

			err := validateRegistrationReq(ctx, req, config.Auth0DatabaseConnection)
			So(err, ShouldBeNil)
		})
	})

	Convey("Registration source", t, func() {
		req := &central.RegistrationReq{
			Country:                   "CN",
			FirstName:                 "aaa",
			LastName:                  "bbb",
			Email:                     "test@pingcap.com",
			Job:                       "",
			Company:                   "TEST",
			PhoneNumber:               "11111111111",
			Password:                  "xxxxxxxx",
			AcceptService:             true,
			RecaptchaResponse:         "",
			ThirdPartyAccountProvider: "",
			ThirdPartyAccountToken:    "",
			ConnectionType:            central.RegistrationReq_EMAIL,
			Auth0Token:                "xxxx",
			Source: &central.RegistrationSource{
				WebsiteReferrerUrl: "abc",
				UtmCampaign:        "a",
				UtmContent:         "b",
				UtmMedium:          "c",
				UtmSource:          "d",
				UtmTerm:            "e",
			},
		}

		clientIP := "114.114.114.114"

		Convey("should build source field if it is not empty", func() {
			params := buildCreateOrgParams(req, clientIP, config.Auth0DatabaseConnection)
			So(params.Source.WebsiteReferrerURL, ShouldEqual, "abc")
			So(params.Source.UtmCampaign, ShouldEqual, "a")
			So(params.Source.UtmContent, ShouldEqual, "b")
			So(params.Source.UtmMedium, ShouldEqual, "c")
			So(params.Source.UtmSource, ShouldEqual, "d")
			So(params.Source.UtmTerm, ShouldEqual, "e")
		})

		Convey("should truncate WebsiteReferrerURL if it is too long", func() {
			req.Source.WebsiteReferrerUrl = util.RandString(300)

			params := buildCreateOrgParams(req, clientIP, config.Auth0DatabaseConnection)
			So(len(params.Source.WebsiteReferrerURL), ShouldEqual, 255)
		})
	})
}
