package iam

import (
	"fmt"
	"net/http"
	"regexp"
	"strings"

	l4g "github.com/alecthomas/log4go"
	"github.com/dailymotion/allure-go"
	"github.com/stretchr/testify/assert"
	"github.com/tidbcloud/qa-PlatformAPIAuto/common"
	"github.com/tidbcloud/qa-gourd/ProductModel"
	"github.com/tidbcloud/qa-gourd/ProductService"
	"github.com/tidbcloud/qa-gourd/handler"
	"github.com/tidbcloud/qa-gourd/util"
)

func RunSignUpTest(w *ProductService.WebRequestInfo, UrlInfoMap map[string]ProductService.UrlInfo, reporter *util.AllureReporter) {
	at := &AccountTest{}
	at.Init(w, UrlInfoMap, reporter)
	at.CheckSignUpScene()
}

func (at *AccountTest) CheckSignUpScene() {
	var signupEmail string
	var err error
	at.Reporter.StepReport("A-SignUp", func() {
		signupEmail, err = at.UserSignUp()
		if err != nil {
			allure.FailNow(err)
		}
	})

	at.Reporter.StepReport("B-Activate", func() {
		err = at.UserActivate(signupEmail)
		if err != nil {
			allure.FailNow(err)
		}
	})

	if handler.EnvFile == ProductModel.Prod {
		at.Reporter.StepReport("CheckSignup - CanNotRunInProd",
			func() {
				assert.True(at.Reporter.T, false)
			})
		return
	}
	at.Reporter.StepReport("C-CheckNewUserProfile", func() {
		// get Original org/user info
		at.SetDBaaSUserInfo(signupEmail)
		at.w.ResetRequestEmail(signupEmail)
		orgId, projectId := at.getOnlyOrgIdProjectIdFromUserProfileV2()
		at.w.ChangeUserInOtherOrg(orgId, projectId, signupEmail)
		at.ResetPathParam(orgId, projectId)
		at.SetDBaaSUserId()
		at.CheckUserProfileScene()
	})
}

// return user email
func (at *AccountTest) userEmailGenerate() string {
	randEmail := UserEmailPrefix + common.RandLowerStr(5) + UserEmailSuffix
	at.Reporter.StepReport(fmt.Sprintf("Generated User Email is : %s", randEmail), func() {
		assert.NotEmpty(at.Reporter.T, randEmail)
	})
	return randEmail
}

// return email and error message
func (at *AccountTest) UserSignUp() (string, error) {
	userEmail := at.userEmailGenerate()
	userSignup := common.NewSignUp(userEmail, handler.OtherUserInfo.LoginPassword)
	signupUserResp := at.w.DoWebAPIRequestByUrlInfo(at.URLInfoMap["register"], userSignup, nil, nil)
	at.Reporter.StepReport(fmt.Sprintf("post SignUp , signup body is : %+v, signup response status code is  : %d",
		userSignup,
		signupUserResp.Raw().StatusCode,
	), func() {
		assert.Equal(at.Reporter.T, http.StatusOK, signupUserResp.Raw().StatusCode)
	})
	if signupUserResp.Raw().StatusCode != http.StatusOK {
		return userEmail, fmt.Errorf("signup failed")
	}
	return userEmail, nil
}

// return org id and error message
func (at *AccountTest) UserActivate(email string) error {
	util.SecondTimeWait(8, 15, "Wait For Activate Email")

	snapmailUrl := []string{"https://www.snapmail.cc", fmt.Sprintf("/emailList/%s", email)}
	getSnapmailResp := common.Get(at.Reporter.T, snapmailUrl, nil, nil, nil)
	l4g.Info("getSnapmailResp:%s", getSnapmailResp.JSON().Raw())
	emailHtml := getSnapmailResp.JSON().Path("$[0].html").String().Raw()
	l4g.Info("%v", emailHtml)
	urlRegexp := regexp.MustCompile(`http://url8461.tidbcloud.com/ls/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]`)
	emailList := urlRegexp.FindStringSubmatch(emailHtml)
	l4g.Info("%v", emailList)
	urlList := strings.Split(emailList[0], "=")
	activateUserResp := common.GetWithRedirect(at.Reporter.T, []string{"http://url8461.tidbcloud.com", "/ls/click"}, nil, nil, map[string]string{"upn": urlList[1]})
	l4g.Info("activateUserResp %s", activateUserResp)
	at.Reporter.StepReport(fmt.Sprintf("Activate SignUp and follow all redirect, activate response status code is  : %d",
		activateUserResp.Raw().StatusCode), func() {
		assert.Equal(at.Reporter.T, http.StatusOK, activateUserResp.Raw().StatusCode)
	})
	if activateUserResp.Raw().StatusCode != http.StatusOK {
		return fmt.Errorf("activate failed")
	}
	return nil
}
