//go:generate ${GOBIN}/mockgen -destination admin_cli_mock.go -package=googlecli ${GO_MODULE}/pkg/infra/clients/googlecli AdminCli
package googlecli

import (
	"context"
	"fmt"
	"strings"

	"golang.org/x/oauth2/google"
	admin "google.golang.org/api/admin/directory/v1"
	"google.golang.org/api/option"
)

type AdminCli interface {
	ListUserEmailsFromSoc2Group() ([]string, error)
}

var _ AdminCli = &adminClient{}

type adminClient struct {
	adminCli *admin.Service
}

func NewAdminClientFromCred(ctx context.Context, cred []byte) (AdminCli, error) {
	adminCred, err := google.CredentialsFromJSONWithTypeAndParams(ctx, cred, google.ServiceAccount, google.CredentialsParams{
		Scopes:  []string{admin.AdminDirectoryGroupMemberReadonlyScope},
		Subject: "shuai.feng@pingcap.com",
	})
	if err != nil {
		return nil, fmt.Errorf("failed to get google admin service credentials: %w", err)
	}
	adminCli, err := admin.NewService(ctx, option.WithCredentials(adminCred))
	if err != nil {
		return nil, fmt.Errorf("failed to retrieve directory Client %v", err)
	}
	return &adminClient{adminCli: adminCli}, nil
}

func (c *adminClient) ListUserEmailsFromSoc2Group() ([]string, error) {
	pageToken := ""
	emails := make([]string, 0)
	for {
		r, err := c.adminCli.Members.List("soc2@pingcap.com").PageToken(pageToken).Do()
		if err != nil {
			return nil, fmt.Errorf("unable to retrieve group members in domain: %v", err)
		}
		pageToken = r.NextPageToken
		for _, member := range r.Members {
			emails = append(emails, strings.ToLower(member.Email))
		}
		if r.NextPageToken == "" {
			break
		}
	}
	return emails, nil
}
