//go:generate ${GOBIN}/dummygen -d=google_cli_dummy.go -package=googlecli ${GO_MODULE}/pkg/infra/clients/googlecli GoogleClient
package googlecli

import (
	"context"
	"fmt"

	"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
	"golang.org/x/oauth2/google"

	"github.com/tidbcloud/devops/pkg/infra/clients/awscli"
	"github.com/tidbcloud/devops/pkg/infra/config"
)

type GoogleClient interface {
	Admin() AdminCli
	BigQuery() BigQueryCli
	Sheets() SheetsCli
}

type googleClient struct {
	adminCli    AdminCli
	bigQueryCli BigQueryCli
	sheetsCli   SheetsCli
}

func (g *googleClient) Admin() AdminCli {
	return g.adminCli
}

func (g *googleClient) BigQuery() BigQueryCli {
	return g.bigQueryCli
}

func (g *googleClient) Sheets() SheetsCli {
	return g.sheetsCli
}

func NewGoogleClient(conf *config.RootConfig, awsCli awscli.AWSClient) (GoogleClient, error) {
	ctx := context.Background()

	if conf.Clients.GCP.Dummy {
		return &DummyGoogleClient{}, nil
	}

	// read secret from AWS Secret Manager
	input := &secretsmanager.GetSecretValueInput{
		SecretId: conf.Clients.GCP.SecretName,
	}
	output, err := awsCli.ASM().GetSecretValue(ctx, input, func(o *secretsmanager.Options) {
		o.Region = conf.Clients.GCP.Region
	})
	if err != nil {
		return nil, fmt.Errorf("failed to get secret from ASM: %w", err)
	}

	c := &googleClient{}

	cred, err := google.CredentialsFromJSONWithTypeAndParams(ctx, []byte(*output.SecretString), google.ServiceAccount, google.CredentialsParams{
		Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"},
	})
	if err != nil {
		return nil, fmt.Errorf("failed to build credentials: %w", err)
	}

	c.adminCli, err = NewAdminClientFromCred(ctx, []byte(*output.SecretString))
	if err != nil {
		return nil, err
	}

	c.bigQueryCli, err = NewBigQueryClientFromCred(ctx, cred, conf.Clients.GCP.ProjectID)
	if err != nil {
		return nil, err
	}

	c.sheetsCli, err = NewSheetsClientFromCred(ctx, []byte(*output.SecretString))
	if err != nil {
		return nil, err
	}

	return c, nil
}
