package service

import (
	"context"
	"os"
	"strings"
	"sync"

	"github.com/spf13/viper"
	admin "google.golang.org/api/admin/directory/v1"
	"google.golang.org/api/groupssettings/v1"

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

func (s *sgeService) GroupOpen() {
	ctx := context.Background()
	log.L(ctx).Infof("Start to open group")

	userEmail := "liuy@pingcap.com"
	serviceAccountFile := viper.GetString("google.service-account")
	adminScope := []string{
		admin.AdminDirectoryGroupMemberScope,
		admin.AdminDirectoryGroupScope,
	}
	serviceAccount, err := os.ReadFile(serviceAccountFile)
	if err != nil {
		log.Fatalf("Error loading golden file: %s", err)
	}
	adminSrv, err := google.NewAdminSrv(ctx, userEmail, serviceAccount, adminScope...)
	if err != nil {
		log.L(ctx).Errorf("Error when calling `NewAdminServiceWithCre`: %s", err.Error())

		return
	}
	directoryService, err := google.NewDirectoryService(adminSrv)
	if err != nil {
		log.L(ctx).Errorf("Error when calling `NewDirectoryService`: %s", err.Error())

		return
	}

	gsScope := []string{
		groupssettings.AppsGroupsSettingsScope,
	}
	gsSrv, err := google.NewGroupsSettingService(ctx, userEmail, serviceAccount, gsScope...)
	if err != nil {
		log.L(ctx).Errorf("Error when calling `NewGroupsSetServiceWithCre`: %s", err.Error())

		return
	}
	groupsSetService, err := google.NewGroupsSetService(gsSrv)
	if err != nil {
		log.L(ctx).Errorf("Error when calling `NewGroupsSetService`: %s", err.Error())

		return
	}

	groups, err := directoryService.ListGroups(ctx, []string{})
	if err != nil {
		log.L(ctx).Errorf("Error when calling `directoryService.ListGroups`: %s", err.Error())

		return
	}
	var wg sync.WaitGroup
	groupChan := make(chan int, 10)
	for _, group := range groups {
		if strings.HasPrefix(group.Name, DeptNamePre+"-") && strings.HasPrefix(group.Email, Pre+"-") && strings.Contains(group.Description, Pre+":") {
			groupChan <- 1
			wg.Add(1)
			go func(groupId string) {
				defer func() {
					wg.Done()
					<-groupChan
				}()
				log.L(ctx).Debugf("Start to open group: %s", groupId)

				groupSetInfo, err := groupsSetService.GetGroupById(ctx, groupId)
				if err != nil {
					log.L(ctx).Errorf("Error when calling `groupsSetService.GetGroupById`: %s", err.Error())

					return
				}
				if groupSetInfo.WhoCanJoin != "INVITED_CAN_JOIN" ||
					groupSetInfo.WhoCanPostMessage != "ALL_IN_DOMAIN_CAN_POST" ||
					groupSetInfo.WhoCanViewMembership != "ALL_IN_DOMAIN_CAN_VIEW" ||
					groupSetInfo.WhoCanViewGroup != "ALL_MEMBERS_CAN_VIEW" {
					groupsSetService.UpdateGroupOpen(ctx, groupId)
				}

			}(group.Email)
		}
	}
	wg.Wait()

	log.L(ctx).Info("Finish to open group")
}
