package service

import (
	"context"
	sync2 "sync"

	authingmodel "github.com/Authing/authing-go-sdk/lib/model"

	"github.com/pingcap-inc/it-automation/pkg/log"
	"github.com/pingcap-inc/it-automation/pkg/provider/authing"
)

var officeEmails = []string{
	"bj-office@pingcap.com",
	"sh-office@pingcap.com",
	"gz-office@pingcap.com",
	"sz-office@pingcap.com",
	"hz-office@pingcap.com",
	"cd-office@pingcap.com",
	"sg-office@pingcap.com",
	"sv-office@pingcap.com",
	"tokyo-office@pingcap.com",
	"nj-office@pingcap.com",
}

func (s *sgeService) CheckRegionEmail(ctx context.Context) {
	log.L(ctx).Info("CheckRegionEmail service function called")

	authingService := authing.NewAuthingService()
	googleService, err := NewGoogleService(ctx)
	if err != nil {
		log.L(ctx).Errorf("Error when calling `NewGoogleService`: %s", err.Error())

		return
	}
	users, err := authingService.GetUsers(ctx)
	if err != nil {
		log.L(ctx).Errorf("Error when calling `authingService.GetUsers`: %s", err.Error())

		return
	}

	wg := sync2.WaitGroup{}
	userChan := make(chan int, 8)
	for _, user := range users {
		wg.Add(1)
		userChan <- 1
		go func(userInFunc authingmodel.User) {
			defer func() {
				<-userChan
				wg.Done()
			}()
			if userInFunc.Email == nil {
				return
			}
			var officeEmail string
			for _, customData := range userInFunc.CustomData {
				if customData.Key == "officeName" {
					officeEmail = *customData.Value
				}
			}

			if officeEmail == "" {
				log.L(ctx).Warnf("userInFunc %s has no office email", *userInFunc.Username)

				return
			}
			isMember, err := IsGroupMember(ctx, googleService, officeEmail, *userInFunc.Email)
			if err != nil {
				log.L(ctx).Errorf("Error when calling `IsGroupMember`: %s", err.Error())

				return
			}

			if !isMember {
				err := insertMember(ctx, googleService, officeEmail, *userInFunc.Email)
				if err != nil {
					log.L(ctx).Errorf("Error when calling `insertMember`: %s", err.Error())

					return
				}
			}
			log.L(ctx).Debugf("userInFunc %s has office email %s", *userInFunc.Username, officeEmail)
		}(user)
	}
	wg.Wait()

	for _, office := range officeEmails {
		result, err := googleService.Members.List(office).Do()
		if err != nil {
			log.L(ctx).Errorf("Error when calling `googleService.Members.List`: %s", err.Error())

			return
		}
		for _, member := range result.Members {
			if member.Type == "EXTERNAL" || member.Status != "ACTIVE" {
				err := googleService.Members.Delete(office, member.Email).Do()
				if err != nil {
					log.L(ctx).Errorf("Error when calling `googleService.Members.Delete(group.Email, member.Email).Do()`: %s", err.Error())
				}
				log.L(ctx).Infof("Delete member success: %s %s", member.Email, office)
			}
		}
	}

	log.L(ctx).Info("CheckRegionEmail service function finished")
}
