// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package acctest

import (
	"context"
	"fmt"
	"log"
	"os"
	"strings"
	"testing"
	"time"

	"github.com/hashicorp/terraform-provider-google-beta/google-beta/envvar"
	tpgcompute "github.com/hashicorp/terraform-provider-google-beta/google-beta/services/compute"
	"github.com/hashicorp/terraform-provider-google-beta/google-beta/services/privateca"
	"github.com/hashicorp/terraform-provider-google-beta/google-beta/services/resourcemanager"
	tpgservicenetworking "github.com/hashicorp/terraform-provider-google-beta/google-beta/services/servicenetworking"
	"github.com/hashicorp/terraform-provider-google-beta/google-beta/services/sql"
	"github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgiamresource"
	"github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource"
	transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport"

	"google.golang.org/api/cloudbilling/v1"
	cloudkms "google.golang.org/api/cloudkms/v1"
	cloudresourcemanager "google.golang.org/api/cloudresourcemanager/v1"
	iam "google.golang.org/api/iam/v1"
	"google.golang.org/api/iamcredentials/v1"
	"google.golang.org/api/servicenetworking/v1"
	"google.golang.org/api/serviceusage/v1"
	sqladmin "google.golang.org/api/sqladmin/v1beta4"
)

var SharedKeyRing = "tftest-shared-keyring-1"
var SharedCryptoKey = map[string]string{
	"ENCRYPT_DECRYPT":    "tftest-shared-key-1",
	"ASYMMETRIC_SIGN":    "tftest-shared-sign-key-1",
	"ASYMMETRIC_DECRYPT": "tftest-shared-decrypt-key-1",
}

type BootstrappedKMS struct {
	*cloudkms.KeyRing
	*cloudkms.CryptoKey
}

func BootstrapKMSKey(t *testing.T) BootstrappedKMS {
	return BootstrapKMSKeyInLocation(t, "global")
}

func BootstrapKMSKeyInLocation(t *testing.T, locationID string) BootstrappedKMS {
	return BootstrapKMSKeyWithPurposeInLocation(t, "ENCRYPT_DECRYPT", locationID)
}

// BootstrapKMSKeyWithPurpose returns a KMS key in the "global" location.
// See BootstrapKMSKeyWithPurposeInLocation.
func BootstrapKMSKeyWithPurpose(t *testing.T, purpose string) BootstrappedKMS {
	return BootstrapKMSKeyWithPurposeInLocation(t, purpose, "global")
}

/**
* BootstrapKMSKeyWithPurposeInLocation will return a KMS key in a
* particular location with the given purpose that can be used
* in tests that are testing KMS integration with other resources.
*
* This will either return an existing key or create one if it hasn't been created
* in the project yet. The motivation is because keyrings don't get deleted and we
* don't want a linear growth of disabled keyrings in a project. We also don't want
* to incur the overhead of creating a new project for each test that needs to use
* a KMS key.
**/
func BootstrapKMSKeyWithPurposeInLocation(t *testing.T, purpose, locationID string) BootstrappedKMS {
	return BootstrapKMSKeyWithPurposeInLocationAndName(t, purpose, locationID, SharedCryptoKey[purpose])
}

func BootstrapKMSKeyWithPurposeInLocationAndName(t *testing.T, purpose, locationID, keyShortName string) BootstrappedKMS {
	config := BootstrapConfig(t)
	if config == nil {
		return BootstrappedKMS{
			&cloudkms.KeyRing{},
			&cloudkms.CryptoKey{},
		}
	}

	projectID := envvar.GetTestProjectFromEnv()
	keyRingParent := fmt.Sprintf("projects/%s/locations/%s", projectID, locationID)
	keyRingName := fmt.Sprintf("%s/keyRings/%s", keyRingParent, SharedKeyRing)
	keyParent := fmt.Sprintf("projects/%s/locations/%s/keyRings/%s", projectID, locationID, SharedKeyRing)
	keyName := fmt.Sprintf("%s/cryptoKeys/%s", keyParent, keyShortName)

	// Get or Create the hard coded shared keyring for testing
	kmsClient := config.NewKmsClient(config.UserAgent)
	keyRing, err := kmsClient.Projects.Locations.KeyRings.Get(keyRingName).Do()
	if err != nil {
		if transport_tpg.IsGoogleApiErrorWithCode(err, 404) {
			keyRing, err = kmsClient.Projects.Locations.KeyRings.Create(keyRingParent, &cloudkms.KeyRing{}).
				KeyRingId(SharedKeyRing).Do()
			if err != nil {
				t.Errorf("Unable to bootstrap KMS key. Cannot create keyRing: %s", err)
			}
		} else {
			t.Errorf("Unable to bootstrap KMS key. Cannot retrieve keyRing: %s", err)
		}
	}

	if keyRing == nil {
		t.Fatalf("Unable to bootstrap KMS key. keyRing is nil!")
	}

	// Get or Create the hard coded, shared crypto key for testing
	cryptoKey, err := kmsClient.Projects.Locations.KeyRings.CryptoKeys.Get(keyName).Do()
	if err != nil {
		if transport_tpg.IsGoogleApiErrorWithCode(err, 404) {
			algos := map[string]string{
				"ENCRYPT_DECRYPT":    "GOOGLE_SYMMETRIC_ENCRYPTION",
				"ASYMMETRIC_SIGN":    "RSA_SIGN_PKCS1_4096_SHA512",
				"ASYMMETRIC_DECRYPT": "RSA_DECRYPT_OAEP_4096_SHA512",
			}
			template := cloudkms.CryptoKeyVersionTemplate{
				Algorithm: algos[purpose],
			}

			newKey := cloudkms.CryptoKey{
				Purpose:         purpose,
				VersionTemplate: &template,
			}

			cryptoKey, err = kmsClient.Projects.Locations.KeyRings.CryptoKeys.Create(keyParent, &newKey).
				CryptoKeyId(keyShortName).Do()
			if err != nil {
				t.Errorf("Unable to bootstrap KMS key. Cannot create new CryptoKey: %s", err)
			}

		} else {
			t.Errorf("Unable to bootstrap KMS key. Cannot call CryptoKey service: %s", err)
		}
	}

	if cryptoKey == nil {
		t.Fatalf("Unable to bootstrap KMS key. CryptoKey is nil!")
	}

	return BootstrappedKMS{
		keyRing,
		cryptoKey,
	}
}

var serviceAccountPrefix = "tf-bootstrap-sa-"
var serviceAccountDisplay = "Bootstrapped Service Account for Terraform tests"

// Some tests need a second service account, other than the test runner, to assert functionality on.
// This provides a well-known service account that can be used when dynamically creating a service
// account isn't an option.
func getOrCreateServiceAccount(config *transport_tpg.Config, project, serviceAccountEmail string) (*iam.ServiceAccount, error) {
	name := fmt.Sprintf("projects/%s/serviceAccounts/%s@%s.iam.gserviceaccount.com", project, serviceAccountEmail, project)
	log.Printf("[DEBUG] Verifying %s as bootstrapped service account.\n", name)

	sa, err := config.NewIamClient(config.UserAgent).Projects.ServiceAccounts.Get(name).Do()
	if err != nil && !transport_tpg.IsGoogleApiErrorWithCode(err, 404) {
		return nil, err
	}

	if sa == nil {
		log.Printf("[DEBUG] Account missing. Creating %s as bootstrapped service account.\n", name)
		sa = &iam.ServiceAccount{
			DisplayName: serviceAccountDisplay,
		}

		r := &iam.CreateServiceAccountRequest{
			AccountId:      serviceAccountEmail,
			ServiceAccount: sa,
		}
		sa, err = config.NewIamClient(config.UserAgent).Projects.ServiceAccounts.Create("projects/"+project, r).Do()
		if err != nil {
			return nil, err
		}
	}

	return sa, nil
}

// In order to test impersonation we need to grant the testRunner's account the ability to grant tokens
// on a different service account. Granting permissions takes time and there is no operation to wait on
// so instead this creates a single service account once per test-suite with the correct permissions.
// The first time this test is run it will fail, but subsequent runs will succeed.
func impersonationServiceAccountPermissions(config *transport_tpg.Config, sa *iam.ServiceAccount, testRunner string) error {
	log.Printf("[DEBUG] Setting service account permissions.\n")
	policy := iam.Policy{
		Bindings: []*iam.Binding{},
	}

	binding := &iam.Binding{
		Role:    "roles/iam.serviceAccountTokenCreator",
		Members: []string{"serviceAccount:" + sa.Email, "serviceAccount:" + testRunner},
	}
	policy.Bindings = append(policy.Bindings, binding)

	// Overwrite the roles each time on this service account. This is because this account is
	// only created for the test suite and will stop snowflaking of permissions to get tests
	// to run. Overwriting permissions on 1 service account shouldn't affect others.
	_, err := config.NewIamClient(config.UserAgent).Projects.ServiceAccounts.SetIamPolicy(sa.Name, &iam.SetIamPolicyRequest{
		Policy: &policy,
	}).Do()
	if err != nil {
		return err
	}

	return nil
}

// A separate testId should be used for each test, to create separate service accounts for each,
// and avoid race conditions where the policy of the same service account is being modified by 2
// tests at once. This is needed as long as the function overwrites the policy on every run.
func BootstrapServiceAccount(t *testing.T, testId, testRunner string) string {
	project := envvar.GetTestProjectFromEnv()
	serviceAccountEmail := serviceAccountPrefix + testId

	config := BootstrapConfig(t)
	if config == nil {
		return ""
	}

	sa, err := getOrCreateServiceAccount(config, project, serviceAccountEmail)
	if err != nil {
		t.Fatalf("Bootstrapping failed. Cannot retrieve service account, %s", err)
	}

	err = impersonationServiceAccountPermissions(config, sa, testRunner)
	if err != nil {
		t.Fatalf("Bootstrapping failed. Cannot set service account permissions, %s", err)
	}

	return sa.Email
}

const SharedTestADDomainPrefix = "tf-bootstrap-ad"

func BootstrapSharedTestADDomain(t *testing.T, testId string, networkName string) string {
	project := envvar.GetTestProjectFromEnv()
	sharedADDomain := fmt.Sprintf("%s.%s.com", SharedTestADDomainPrefix, testId)
	adDomainName := fmt.Sprintf("projects/%s/locations/global/domains/%s", project, sharedADDomain)

	config := BootstrapConfig(t)
	if config == nil {
		return ""
	}

	log.Printf("[DEBUG] Getting shared test active directory domain %q", adDomainName)
	getURL := fmt.Sprintf("%s%s", config.ActiveDirectoryBasePath, adDomainName)
	_, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
		Config:    config,
		Method:    "GET",
		Project:   project,
		RawURL:    getURL,
		UserAgent: config.UserAgent,
		Timeout:   4 * time.Minute,
	})
	if err != nil && transport_tpg.IsGoogleApiErrorWithCode(err, 404) {
		log.Printf("[DEBUG] AD domain %q not found, bootstrapping", sharedADDomain)
		postURL := fmt.Sprintf("%sprojects/%s/locations/global/domains?domainName=%s", config.ActiveDirectoryBasePath, project, sharedADDomain)
		domainObj := map[string]interface{}{
			"locations":          []string{"us-central1"},
			"reservedIpRange":    "10.0.1.0/24",
			"authorizedNetworks": []string{fmt.Sprintf("projects/%s/global/networks/%s", project, networkName)},
		}

		_, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
			Config:    config,
			Method:    "POST",
			Project:   project,
			RawURL:    postURL,
			UserAgent: config.UserAgent,
			Body:      domainObj,
			Timeout:   60 * time.Minute,
		})
		if err != nil {
			t.Fatalf("Error bootstrapping shared active directory domain %q: %s", adDomainName, err)
		}

		log.Printf("[DEBUG] Waiting for active directory domain creation to finish")
	}

	_, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
		Config:    config,
		Method:    "GET",
		Project:   project,
		RawURL:    getURL,
		UserAgent: config.UserAgent,
		Timeout:   4 * time.Minute,
	})

	if err != nil {
		t.Fatalf("Error getting shared active directory domain %q: %s", adDomainName, err)
	}

	return sharedADDomain
}

const SharedTestNetworkPrefix = "tf-bootstrap-net-"

// BootstrapSharedTestNetwork will return a persistent compute network for a
// test or set of tests.
//
// Usage 1
// Resources like service_networking_connection use a consumer network and
// create a complementing tenant network which we don't control. These tenant
// networks never get cleaned up and they can accumulate to the point where a
// limit is reached for the organization. By reusing a consumer network across
// test runs, we can reduce the number of tenant networks that are needed.
// See b/146351146 for more context.
//
// Usage 2
// Bootstrap networks used in tests (gke clusters, dataproc clusters...)
// to avoid traffic to the default network
//
// testId specifies the test for which a shared network is used/initialized.
// Note that if the network is being used for a service_networking_connection,
// the same testId should generally not be used across tests, to avoid race
// conditions where multiple tests attempt to modify the connection at once.
//
// Returns the name of a network, creating it if it hasn't been created in the
// test project.
func BootstrapSharedTestNetwork(t *testing.T, testId string) string {
	project := envvar.GetTestProjectFromEnv()
	networkName := SharedTestNetworkPrefix + testId

	config := BootstrapConfig(t)
	if config == nil {
		return ""
	}

	log.Printf("[DEBUG] Getting shared test network %q", networkName)
	_, err := config.NewComputeClient(config.UserAgent).Networks.Get(project, networkName).Do()
	if err != nil && transport_tpg.IsGoogleApiErrorWithCode(err, 404) {
		log.Printf("[DEBUG] Network %q not found, bootstrapping", networkName)
		url := fmt.Sprintf("%sprojects/%s/global/networks", config.ComputeBasePath, project)
		netObj := map[string]interface{}{
			"name":                  networkName,
			"autoCreateSubnetworks": false,
		}

		res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
			Config:    config,
			Method:    "POST",
			Project:   project,
			RawURL:    url,
			UserAgent: config.UserAgent,
			Body:      netObj,
			Timeout:   4 * time.Minute,
		})
		if err != nil {
			t.Fatalf("Error bootstrapping shared test network %q: %s", networkName, err)
		}

		log.Printf("[DEBUG] Waiting for network creation to finish")
		err = tpgcompute.ComputeOperationWaitTime(config, res, project, "Error bootstrapping shared test network", config.UserAgent, 4*time.Minute)
		if err != nil {
			t.Fatalf("Error bootstrapping shared test network %q: %s", networkName, err)
		}
	}

	network, err := config.NewComputeClient(config.UserAgent).Networks.Get(project, networkName).Do()
	if err != nil {
		t.Errorf("Error getting shared test network %q: %s", networkName, err)
	}
	if network == nil {
		t.Fatalf("Error getting shared test network %q: is nil", networkName)
	}
	return network.Name
}

type AddressSettings struct {
	PrefixLength int
}

func AddressWithPrefixLength(prefixLength int) func(*AddressSettings) {
	return func(settings *AddressSettings) {
		settings.PrefixLength = prefixLength
	}
}

func NewAddressSettings(options ...func(*AddressSettings)) *AddressSettings {
	settings := &AddressSettings{
		PrefixLength: 16, // default prefix length
	}

	for _, o := range options {
		o(settings)
	}
	return settings
}

const SharedTestGlobalAddressPrefix = "tf-bootstrap-addr-"

// params are the functions to set compute global address
func BootstrapSharedTestGlobalAddress(t *testing.T, testId string, params ...func(*AddressSettings)) string {
	project := envvar.GetTestProjectFromEnv()
	addressName := SharedTestGlobalAddressPrefix + testId
	networkName := BootstrapSharedTestNetwork(t, testId)
	networkId := fmt.Sprintf("projects/%v/global/networks/%v", project, networkName)

	config := BootstrapConfig(t)
	if config == nil {
		return ""
	}

	log.Printf("[DEBUG] Getting shared test global address %q", addressName)
	_, err := config.NewComputeClient(config.UserAgent).GlobalAddresses.Get(project, addressName).Do()
	if err != nil && transport_tpg.IsGoogleApiErrorWithCode(err, 404) {
		log.Printf("[DEBUG] Global address %q not found, bootstrapping", addressName)
		url := fmt.Sprintf("%sprojects/%s/global/addresses", config.ComputeBasePath, project)

		settings := NewAddressSettings(params...)

		netObj := map[string]interface{}{
			"name":          addressName,
			"address_type":  "INTERNAL",
			"purpose":       "VPC_PEERING",
			"prefix_length": settings.PrefixLength,
			"network":       networkId,
		}

		res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
			Config:    config,
			Method:    "POST",
			Project:   project,
			RawURL:    url,
			UserAgent: config.UserAgent,
			Body:      netObj,
			Timeout:   4 * time.Minute,
		})
		if err != nil {
			t.Fatalf("Error bootstrapping shared test global address %q: %s", addressName, err)
		}

		log.Printf("[DEBUG] Waiting for global address creation to finish")
		err = tpgcompute.ComputeOperationWaitTime(config, res, project, "Error bootstrapping shared test global address", config.UserAgent, 4*time.Minute)
		if err != nil {
			t.Fatalf("Error bootstrapping shared test global address %q: %s", addressName, err)
		}
	}

	address, err := config.NewComputeClient(config.UserAgent).GlobalAddresses.Get(project, addressName).Do()
	if err != nil {
		t.Errorf("Error getting shared test global address %q: %s", addressName, err)
	}
	if address == nil {
		t.Fatalf("Error getting shared test global address %q: is nil", addressName)
	}
	return address.Name
}

type ServiceNetworkSettings struct {
	PrefixLength  int
	ParentService string
}

func ServiceNetworkWithPrefixLength(prefixLength int) func(*ServiceNetworkSettings) {
	return func(settings *ServiceNetworkSettings) {
		settings.PrefixLength = prefixLength
	}
}

func ServiceNetworkWithParentService(parentService string) func(*ServiceNetworkSettings) {
	return func(settings *ServiceNetworkSettings) {
		settings.ParentService = parentService
	}
}

func NewServiceNetworkSettings(options ...func(*ServiceNetworkSettings)) *ServiceNetworkSettings {
	settings := &ServiceNetworkSettings{
		PrefixLength:  16,                                 // default prefix length
		ParentService: "servicenetworking.googleapis.com", // default parent service
	}

	for _, o := range options {
		o(settings)
	}
	return settings
}

// BootstrapSharedServiceNetworkingConnection will create a shared network
// if it hasn't been created in the test project, a global address
// if it hasn't been created in the test project, and a service networking connection
// if it hasn't been created in the test project.
//
// params are the functions to set compute global address
//
// BootstrapSharedServiceNetworkingConnection returns a persistent compute network name
// for a test or set of tests.
//
// To delete a service networking conneciton, all of the service instances that use that connection
// must be deleted first. After the service instances are deleted, some service producers delay the deletion
// utnil a waiting period has passed. For example, after four days that you delete a SQL instance,
// the service networking connection can be deleted.
// That is the reason to use the shared service networking connection for thest resources.
// https://cloud.google.com/vpc/docs/configure-private-services-access#removing-connection
//
// testId specifies the test for which a shared network and a gobal address are used/initialized.
func BootstrapSharedServiceNetworkingConnection(t *testing.T, testId string, params ...func(*ServiceNetworkSettings)) string {
	settings := NewServiceNetworkSettings(params...)
	parentService := "services/" + settings.ParentService
	projectId := envvar.GetTestProjectFromEnv()

	config := BootstrapConfig(t)
	if config == nil {
		return ""
	}

	// Get project number by calling the API
	crmClient := config.NewResourceManagerClient(config.UserAgent)
	project, err := crmClient.Projects.Get(projectId).Do()
	if err != nil {
		t.Fatalf("Error getting project: %s", err)
	}

	networkName := SharedTestNetworkPrefix + testId
	networkId := fmt.Sprintf("projects/%v/global/networks/%v", project.ProjectNumber, networkName)
	globalAddressName := BootstrapSharedTestGlobalAddress(t, testId, AddressWithPrefixLength(settings.PrefixLength))

	readCall := config.NewServiceNetworkingClient(config.UserAgent).Services.Connections.List(parentService).Network(networkId)
	if config.UserProjectOverride {
		readCall.Header().Add("X-Goog-User-Project", projectId)
	}
	response, err := readCall.Do()
	if err != nil {
		t.Errorf("Error getting shared test service networking connection: %s", err)
	}

	var connection *servicenetworking.Connection
	for _, c := range response.Connections {
		if c.Network == networkId {
			connection = c
			break
		}
	}

	if connection == nil {
		log.Printf("[DEBUG] Service networking connection not found, bootstrapping")

		connection := &servicenetworking.Connection{
			Network:               networkId,
			ReservedPeeringRanges: []string{globalAddressName},
		}

		createCall := config.NewServiceNetworkingClient(config.UserAgent).Services.Connections.Create(parentService, connection)
		if config.UserProjectOverride {
			createCall.Header().Add("X-Goog-User-Project", projectId)
		}
		op, err := createCall.Do()
		if err != nil {
			t.Fatalf("Error bootstrapping shared test service networking connection: %s", err)
		}

		log.Printf("[DEBUG] Waiting for service networking connection creation to finish")
		if err := tpgservicenetworking.ServiceNetworkingOperationWaitTimeHW(config, op, "Create Service Networking Connection", config.UserAgent, projectId, 4*time.Minute); err != nil {
			t.Fatalf("Error bootstrapping shared test service networking connection: %s", err)
		}
	}

	log.Printf("[DEBUG] Getting shared test service networking connection")

	return networkName
}

var SharedServicePerimeterProjectPrefix = "tf-bootstrap-sp-"

func BootstrapServicePerimeterProjects(t *testing.T, desiredProjects int) []*cloudresourcemanager.Project {
	config := BootstrapConfig(t)
	if config == nil {
		return nil
	}

	org := envvar.GetTestOrgFromEnv(t)

	// The filter endpoint works differently if you provide both the parent id and parent type, and
	// doesn't seem to allow for prefix matching. Don't change this to include the parent type unless
	// that API behavior changes.
	prefixFilter := fmt.Sprintf("id:%s* parent.id:%s", SharedServicePerimeterProjectPrefix, org)
	res, err := config.NewResourceManagerClient(config.UserAgent).Projects.List().Filter(prefixFilter).Do()
	if err != nil {
		t.Fatalf("Error getting shared test projects: %s", err)
	}

	projects := res.Projects
	for len(projects) < desiredProjects {
		pid := SharedServicePerimeterProjectPrefix + RandString(t, 10)
		project := &cloudresourcemanager.Project{
			ProjectId: pid,
			Name:      "TF Service Perimeter Test",
			Parent: &cloudresourcemanager.ResourceId{
				Type: "organization",
				Id:   org,
			},
		}
		op, err := config.NewResourceManagerClient(config.UserAgent).Projects.Create(project).Do()
		if err != nil {
			t.Fatalf("Error bootstrapping shared test project: %s", err)
		}

		opAsMap, err := tpgresource.ConvertToMap(op)
		if err != nil {
			t.Fatalf("Error bootstrapping shared test project: %s", err)
		}

		err = resourcemanager.ResourceManagerOperationWaitTime(config, opAsMap, "creating project", config.UserAgent, 4)
		if err != nil {
			t.Fatalf("Error bootstrapping shared test project: %s", err)
		}

		p, err := config.NewResourceManagerClient(config.UserAgent).Projects.Get(pid).Do()
		if err != nil {
			t.Fatalf("Error getting shared test project: %s", err)
		}
		projects = append(projects, p)
	}

	return projects
}

// BootstrapProject will create or get a project named
// "<projectIDPrefix><projectIDSuffix>" that will persist across test runs,
// where projectIDSuffix is based off of getTestProjectFromEnv(). The reason
// for the naming is to isolate bootstrapped projects by test environment.
// Given the existing projects being used by our team, the prefix provided to
// this function can be no longer than 18 characters.
func BootstrapProject(t *testing.T, projectIDPrefix, billingAccount string, services []string) *cloudresourcemanager.Project {
	config := BootstrapConfig(t)
	if config == nil {
		return nil
	}

	projectIDSuffix := strings.Replace(envvar.GetTestProjectFromEnv(), "ci-test-project-", "", 1)
	projectID := projectIDPrefix + projectIDSuffix

	crmClient := config.NewResourceManagerClient(config.UserAgent)

	project, err := crmClient.Projects.Get(projectID).Do()
	if err != nil {
		if !transport_tpg.IsGoogleApiErrorWithCode(err, 403) {
			t.Fatalf("Error getting bootstrapped project: %s", err)
		}
		org := envvar.GetTestOrgFromEnv(t)

		op, err := crmClient.Projects.Create(&cloudresourcemanager.Project{
			ProjectId: projectID,
			Name:      "Bootstrapped Test Project",
			Parent: &cloudresourcemanager.ResourceId{
				Type: "organization",
				Id:   org,
			},
		}).Do()
		if err != nil {
			t.Fatalf("Error creating bootstrapped test project: %s", err)
		}

		opAsMap, err := tpgresource.ConvertToMap(op)
		if err != nil {
			t.Fatalf("Error converting create project operation to map: %s", err)
		}

		err = resourcemanager.ResourceManagerOperationWaitTime(config, opAsMap, "creating project", config.UserAgent, 4*time.Minute)
		if err != nil {
			t.Fatalf("Error waiting for create project operation: %s", err)
		}

		project, err = crmClient.Projects.Get(projectID).Do()
		if err != nil {
			t.Fatalf("Error getting bootstrapped project: %s", err)
		}

	}

	if project.LifecycleState == "DELETE_REQUESTED" {
		_, err := crmClient.Projects.Undelete(projectID, &cloudresourcemanager.UndeleteProjectRequest{}).Do()
		if err != nil {
			t.Fatalf("Error undeleting bootstrapped project: %s", err)
		}
	}

	if billingAccount != "" {
		billingClient := config.NewBillingClient(config.UserAgent)
		var pbi *cloudbilling.ProjectBillingInfo
		err = transport_tpg.Retry(transport_tpg.RetryOptions{
			RetryFunc: func() error {
				var reqErr error
				pbi, reqErr = billingClient.Projects.GetBillingInfo(resourcemanager.PrefixedProject(projectID)).Do()
				return reqErr
			},
			Timeout: 30 * time.Second,
		})
		if err != nil {
			t.Fatalf("Error getting billing info for project %q: %v", projectID, err)
		}
		if strings.TrimPrefix(pbi.BillingAccountName, "billingAccounts/") != billingAccount {
			pbi.BillingAccountName = "billingAccounts/" + billingAccount
			err := transport_tpg.Retry(transport_tpg.RetryOptions{
				RetryFunc: func() error {
					_, err := config.NewBillingClient(config.UserAgent).Projects.UpdateBillingInfo(resourcemanager.PrefixedProject(projectID), pbi).Do()
					return err
				},
				Timeout: 2 * time.Minute,
			})
			if err != nil {
				t.Fatalf("Error setting billing account for project %q to %q: %s", projectID, billingAccount, err)
			}
		}
	}

	if len(services) > 0 {

		enabledServices, err := resourcemanager.ListCurrentlyEnabledServices(projectID, "", config.UserAgent, config, 1*time.Minute)
		if err != nil {
			t.Fatalf("Error listing services for project %q: %s", projectID, err)
		}

		servicesToEnable := make([]string, 0, len(services))
		for _, service := range services {
			if _, ok := enabledServices[service]; !ok {
				servicesToEnable = append(servicesToEnable, service)
			}
		}

		if len(servicesToEnable) > 0 {
			if err := resourcemanager.EnableServiceUsageProjectServices(servicesToEnable, projectID, "", config.UserAgent, config, 10*time.Minute); err != nil {
				t.Fatalf("Error enabling services for project %q: %s", projectID, err)
			}
		}
	}

	return project
}

// BootstrapConfig returns a Config pulled from the environment.
func BootstrapConfig(t *testing.T) *transport_tpg.Config {
	if v := os.Getenv("TF_ACC"); v == "" {
		t.Skip("Acceptance tests and bootstrapping skipped unless env 'TF_ACC' set")
		return nil
	}

	config := &transport_tpg.Config{
		Credentials: envvar.GetTestCredsFromEnv(),
		Project:     envvar.GetTestProjectFromEnv(),
		Region:      envvar.GetTestRegionFromEnv(),
		Zone:        envvar.GetTestZoneFromEnv(),
	}

	transport_tpg.ConfigureBasePaths(config)

	if err := config.LoadAndValidate(context.Background()); err != nil {
		t.Fatalf("Bootstrapping failed. Unable to load test config: %s", err)
	}
	return config
}

// SQL Instance names are not reusable for a week after deletion
const SharedTestSQLInstanceNamePrefix = "tf-bootstrap-"

// BootstrapSharedSQLInstanceBackupRun will return a shared SQL db instance that
// has a backup created for it.
func BootstrapSharedSQLInstanceBackupRun(t *testing.T) string {
	project := envvar.GetTestProjectFromEnv()

	config := BootstrapConfig(t)
	if config == nil {
		return ""
	}

	log.Printf("[DEBUG] Getting list of existing sql instances")

	instances, err := config.NewSqlAdminClient(config.UserAgent).Instances.List(project).Do()
	if err != nil {
		t.Fatalf("Unable to bootstrap SQL Instance. Cannot retrieve instance list: %s", err)
	}

	var bootstrapInstance *sqladmin.DatabaseInstance

	// Look for any existing bootstrap instances
	for _, i := range instances.Items {
		if strings.HasPrefix(i.Name, SharedTestSQLInstanceNamePrefix) {
			bootstrapInstance = i
			break
		}
	}

	if bootstrapInstance == nil {
		bootstrapInstanceName := SharedTestSQLInstanceNamePrefix + RandString(t, 10)
		log.Printf("[DEBUG] Bootstrap SQL Instance not found, bootstrapping new instance %s", bootstrapInstanceName)

		backupConfig := &sqladmin.BackupConfiguration{
			Enabled:                    true,
			PointInTimeRecoveryEnabled: true,
		}
		settings := &sqladmin.Settings{
			Tier:                "db-f1-micro",
			BackupConfiguration: backupConfig,
		}
		bootstrapInstance = &sqladmin.DatabaseInstance{
			Name:            bootstrapInstanceName,
			Region:          "us-central1",
			Settings:        settings,
			DatabaseVersion: "POSTGRES_11",
		}

		var op *sqladmin.Operation
		err = transport_tpg.Retry(transport_tpg.RetryOptions{
			RetryFunc: func() (operr error) {
				op, operr = config.NewSqlAdminClient(config.UserAgent).Instances.Insert(project, bootstrapInstance).Do()
				return operr
			},
			Timeout:              20 * time.Minute,
			ErrorRetryPredicates: []transport_tpg.RetryErrorPredicateFunc{transport_tpg.IsSqlOperationInProgressError},
		})
		if err != nil {
			t.Fatalf("Error, failed to create instance %s: %s", bootstrapInstance.Name, err)
		}
		err = sql.SqlAdminOperationWaitTime(config, op, project, "Create Instance", config.UserAgent, 40*time.Minute)
		if err != nil {
			t.Fatalf("Error, failed to create instance %s: %s", bootstrapInstance.Name, err)
		}
	}

	// Look for backups in bootstrap instance
	res, err := config.NewSqlAdminClient(config.UserAgent).BackupRuns.List(project, bootstrapInstance.Name).Do()
	if err != nil {
		t.Fatalf("Unable to bootstrap SQL Instance. Cannot retrieve backup list: %s", err)
	}
	backupsList := res.Items
	if len(backupsList) == 0 {
		log.Printf("[DEBUG] No backups found for %s, creating backup", bootstrapInstance.Name)
		backupRun := &sqladmin.BackupRun{
			Instance: bootstrapInstance.Name,
		}

		var op *sqladmin.Operation
		err = transport_tpg.Retry(transport_tpg.RetryOptions{
			RetryFunc: func() (operr error) {
				op, operr = config.NewSqlAdminClient(config.UserAgent).BackupRuns.Insert(project, bootstrapInstance.Name, backupRun).Do()
				return operr
			},
			Timeout:              20 * time.Minute,
			ErrorRetryPredicates: []transport_tpg.RetryErrorPredicateFunc{transport_tpg.IsSqlOperationInProgressError},
		})
		if err != nil {
			t.Fatalf("Error, failed to create instance backup: %s", err)
		}
		err = sql.SqlAdminOperationWaitTime(config, op, project, "Backup Instance", config.UserAgent, 20*time.Minute)
		if err != nil {
			t.Fatalf("Error, failed to create instance backup: %s", err)
		}
	}

	return bootstrapInstance.Name
}

func BootstrapSharedCaPoolInLocation(t *testing.T, location string) string {
	project := envvar.GetTestProjectFromEnv()
	poolName := "static-ca-pool"

	config := BootstrapConfig(t)
	if config == nil {
		return ""
	}

	log.Printf("[DEBUG] Getting shared CA pool %q", poolName)
	url := fmt.Sprintf("%sprojects/%s/locations/%s/caPools/%s", config.PrivatecaBasePath, project, location, poolName)
	_, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
		Config:    config,
		Method:    "GET",
		Project:   project,
		RawURL:    url,
		UserAgent: config.UserAgent,
	})
	if err != nil {
		log.Printf("[DEBUG] CA pool %q not found, bootstrapping", poolName)
		poolObj := map[string]interface{}{
			"tier": "ENTERPRISE",
		}
		createUrl := fmt.Sprintf("%sprojects/%s/locations/%s/caPools?caPoolId=%s", config.PrivatecaBasePath, project, location, poolName)
		res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
			Config:    config,
			Method:    "POST",
			Project:   project,
			RawURL:    createUrl,
			UserAgent: config.UserAgent,
			Body:      poolObj,
			Timeout:   4 * time.Minute,
		})
		if err != nil {
			t.Fatalf("Error bootstrapping shared CA pool %q: %s", poolName, err)
		}

		log.Printf("[DEBUG] Waiting for CA pool creation to finish")
		var opRes map[string]interface{}
		err = privateca.PrivatecaOperationWaitTimeWithResponse(
			config, res, &opRes, project, "Creating CA pool", config.UserAgent,
			4*time.Minute)
		if err != nil {
			t.Errorf("Error getting shared CA pool %q: %s", poolName, err)
		}
		_, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
			Config:    config,
			Method:    "GET",
			Project:   project,
			RawURL:    url,
			UserAgent: config.UserAgent,
		})
		if err != nil {
			t.Errorf("Error getting shared CA pool %q: %s", poolName, err)
		}
	}
	return poolName
}

func BootstrapSubnet(t *testing.T, subnetName string, networkName string) string {
	projectID := envvar.GetTestProjectFromEnv()
	region := envvar.GetTestRegionFromEnv()

	config := BootstrapConfig(t)
	if config == nil {
		t.Fatal("Could not bootstrap config.")
	}

	computeService := config.NewComputeClient(config.UserAgent)
	if computeService == nil {
		t.Fatal("Could not create compute client.")
	}

	// In order to create a networkAttachment we need to bootstrap a subnet.
	_, err := computeService.Subnetworks.Get(projectID, region, subnetName).Do()
	if err != nil && transport_tpg.IsGoogleApiErrorWithCode(err, 404) {
		log.Printf("[DEBUG] Subnet %q not found, bootstrapping", subnetName)

		networkUrl := fmt.Sprintf("%sprojects/%s/global/networks/%s", config.ComputeBasePath, projectID, networkName)
		url := fmt.Sprintf("%sprojects/%s/regions/%s/subnetworks", config.ComputeBasePath, projectID, region)

		subnetObj := map[string]interface{}{
			"name":        subnetName,
			"region ":     region,
			"network":     networkUrl,
			"ipCidrRange": "10.77.0.0/20",
		}

		res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
			Config:    config,
			Method:    "POST",
			Project:   projectID,
			RawURL:    url,
			UserAgent: config.UserAgent,
			Body:      subnetObj,
			Timeout:   4 * time.Minute,
		})

		log.Printf("Response is, %s", res)
		if err != nil {
			t.Fatalf("Error bootstrapping test subnet %s: %s", subnetName, err)
		}

		log.Printf("[DEBUG] Waiting for network creation to finish")
		err = tpgcompute.ComputeOperationWaitTime(config, res, projectID, "Error bootstrapping test subnet", config.UserAgent, 4*time.Minute)
		if err != nil {
			t.Fatalf("Error bootstrapping test subnet %s: %s", subnetName, err)
		}
	}

	subnet, err := computeService.Subnetworks.Get(projectID, region, subnetName).Do()

	if subnet == nil {
		t.Fatalf("Error getting test subnet %s: is nil", subnetName)
	}

	if err != nil {
		t.Fatalf("Error getting test subnet %s: %s", subnetName, err)
	}
	return subnet.Name
}

func BootstrapNetworkAttachment(t *testing.T, networkAttachmentName string, subnetName string) string {
	projectID := envvar.GetTestProjectFromEnv()
	region := envvar.GetTestRegionFromEnv()

	config := BootstrapConfig(t)
	if config == nil {
		return ""
	}

	computeService := config.NewComputeClient(config.UserAgent)
	if computeService == nil {
		return ""
	}

	networkAttachment, err := computeService.NetworkAttachments.Get(projectID, region, networkAttachmentName).Do()
	if err != nil && transport_tpg.IsGoogleApiErrorWithCode(err, 404) {
		// Create Network Attachment Here.
		log.Printf("[DEBUG] Network Attachment %s not found, bootstrapping", networkAttachmentName)
		url := fmt.Sprintf("%sprojects/%s/regions/%s/networkAttachments", config.ComputeBasePath, projectID, region)

		subnetURL := fmt.Sprintf("%sprojects/%s/regions/%s/subnetworks/%s", config.ComputeBasePath, projectID, region, subnetName)
		networkAttachmentObj := map[string]interface{}{
			"name":                 networkAttachmentName,
			"region":               region,
			"subnetworks":          []string{subnetURL},
			"connectionPreference": "ACCEPT_AUTOMATIC",
		}

		res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
			Config:    config,
			Method:    "POST",
			Project:   projectID,
			RawURL:    url,
			UserAgent: config.UserAgent,
			Body:      networkAttachmentObj,
			Timeout:   4 * time.Minute,
		})
		if err != nil {
			t.Fatalf("Error bootstrapping test Network Attachment %s: %s", networkAttachmentName, err)
		}

		log.Printf("[DEBUG] Waiting for network creation to finish")
		err = tpgcompute.ComputeOperationWaitTime(config, res, projectID, "Error bootstrapping shared test subnet", config.UserAgent, 4*time.Minute)
		if err != nil {
			t.Fatalf("Error bootstrapping test Network Attachment %s: %s", networkAttachmentName, err)
		}
	}

	networkAttachment, err = computeService.NetworkAttachments.Get(projectID, region, networkAttachmentName).Do()

	if networkAttachment == nil {
		t.Fatalf("Error getting test network attachment %s: is nil", networkAttachmentName)
	}

	if err != nil {
		t.Fatalf("Error getting test Network Attachment %s: %s", networkAttachmentName, err)
	}

	return networkAttachment.Name
}

// The default network within GCP already comes pre configured with
// certain firewall rules open to allow internal communication. As we
// are boostrapping a network for dataproc tests, we need to additionally
// open up similar rules to allow the nodes to talk to each other
// internally as part of their configuration or this will just hang.
const SharedTestFirewallPrefix = "tf-bootstrap-firewall-"

func BootstrapFirewallForDataprocSharedNetwork(t *testing.T, firewallName string, networkName string) string {
	project := envvar.GetTestProjectFromEnv()
	firewallName = SharedTestFirewallPrefix + firewallName

	config := BootstrapConfig(t)
	if config == nil {
		return ""
	}

	log.Printf("[DEBUG] Getting Firewall %q for Network %q", firewallName, networkName)
	_, err := config.NewComputeClient(config.UserAgent).Firewalls.Get(project, firewallName).Do()
	if err != nil && transport_tpg.IsGoogleApiErrorWithCode(err, 404) {
		log.Printf("[DEBUG] firewallName %q not found, bootstrapping", firewallName)
		url := fmt.Sprintf("%sprojects/%s/global/firewalls", config.ComputeBasePath, project)

		networkId := fmt.Sprintf("projects/%s/global/networks/%s", project, networkName)
		allowObj := []interface{}{
			map[string]interface{}{
				"IPProtocol": "icmp",
			},
			map[string]interface{}{
				"IPProtocol": "tcp",
				"ports":      []string{"0-65535"},
			},
			map[string]interface{}{
				"IPProtocol": "udp",
				"ports":      []string{"0-65535"},
			},
		}

		firewallObj := map[string]interface{}{
			"name":    firewallName,
			"network": networkId,
			"allowed": allowObj,
		}

		res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
			Config:    config,
			Method:    "POST",
			Project:   project,
			RawURL:    url,
			UserAgent: config.UserAgent,
			Body:      firewallObj,
			Timeout:   4 * time.Minute,
		})
		if err != nil {
			t.Fatalf("Error bootstrapping Firewall %q for Network %q: %s", firewallName, networkName, err)
		}

		log.Printf("[DEBUG] Waiting for Firewall creation to finish")
		err = tpgcompute.ComputeOperationWaitTime(config, res, project, "Error bootstrapping Firewall", config.UserAgent, 4*time.Minute)
		if err != nil {
			t.Fatalf("Error bootstrapping Firewall %q: %s", firewallName, err)
		}
	}

	firewall, err := config.NewComputeClient(config.UserAgent).Firewalls.Get(project, firewallName).Do()
	if err != nil {
		t.Errorf("Error getting Firewall %q: %s", firewallName, err)
	}
	if firewall == nil {
		t.Fatalf("Error getting Firewall %q: is nil", firewallName)
	}
	return firewall.Name
}

func SetupProjectsAndGetAccessToken(org, billing, pid, service string, config *transport_tpg.Config) (string, error) {
	// Create project-1 and project-2
	rmService := config.NewResourceManagerClient(config.UserAgent)

	project := &cloudresourcemanager.Project{
		ProjectId: pid,
		Name:      pid,
		Parent: &cloudresourcemanager.ResourceId{
			Id:   org,
			Type: "organization",
		},
	}

	var op *cloudresourcemanager.Operation
	err := transport_tpg.Retry(transport_tpg.RetryOptions{
		RetryFunc: func() (reqErr error) {
			op, reqErr = rmService.Projects.Create(project).Do()
			return reqErr
		},
		Timeout: 5 * time.Minute,
	})
	if err != nil {
		return "", err
	}

	// Wait for the operation to complete
	opAsMap, err := tpgresource.ConvertToMap(op)
	if err != nil {
		return "", err
	}

	waitErr := resourcemanager.ResourceManagerOperationWaitTime(config, opAsMap, "creating project", config.UserAgent, 5*time.Minute)
	if waitErr != nil {
		return "", waitErr
	}

	ba := &cloudbilling.ProjectBillingInfo{
		BillingAccountName: fmt.Sprintf("billingAccounts/%s", billing),
	}
	_, err = config.NewBillingClient(config.UserAgent).Projects.UpdateBillingInfo(resourcemanager.PrefixedProject(pid), ba).Do()
	if err != nil {
		return "", err
	}

	p2 := fmt.Sprintf("%s-2", pid)
	project.ProjectId = p2
	project.Name = fmt.Sprintf("%s-2", pid)

	err = transport_tpg.Retry(transport_tpg.RetryOptions{
		RetryFunc: func() (reqErr error) {
			op, reqErr = rmService.Projects.Create(project).Do()
			return reqErr
		},
		Timeout: 5 * time.Minute,
	})
	if err != nil {
		return "", err
	}

	// Wait for the operation to complete
	opAsMap, err = tpgresource.ConvertToMap(op)
	if err != nil {
		return "", err
	}

	waitErr = resourcemanager.ResourceManagerOperationWaitTime(config, opAsMap, "creating project", config.UserAgent, 5*time.Minute)
	if waitErr != nil {
		return "", waitErr
	}

	_, err = config.NewBillingClient(config.UserAgent).Projects.UpdateBillingInfo(resourcemanager.PrefixedProject(p2), ba).Do()
	if err != nil {
		return "", err
	}

	// Enable the appropriate service in project-2 only
	suService := config.NewServiceUsageClient(config.UserAgent)

	serviceReq := &serviceusage.BatchEnableServicesRequest{
		ServiceIds: []string{fmt.Sprintf("%s.googleapis.com", service)},
	}

	_, err = suService.Services.BatchEnable(fmt.Sprintf("projects/%s", p2), serviceReq).Do()
	if err != nil {
		return "", err
	}

	// Enable the test runner to create service accounts and get an access token on behalf of
	// the project 1 service account
	curEmail, err := transport_tpg.GetCurrentUserEmail(config, config.UserAgent)
	if err != nil {
		return "", err
	}

	proj1SATokenCreator := &cloudresourcemanager.Binding{
		Members: []string{fmt.Sprintf("serviceAccount:%s", curEmail)},
		Role:    "roles/iam.serviceAccountTokenCreator",
	}

	proj1SACreator := &cloudresourcemanager.Binding{
		Members: []string{fmt.Sprintf("serviceAccount:%s", curEmail)},
		Role:    "roles/iam.serviceAccountCreator",
	}

	bindings := tpgiamresource.MergeBindings([]*cloudresourcemanager.Binding{proj1SATokenCreator, proj1SACreator})

	p, err := rmService.Projects.GetIamPolicy(pid,
		&cloudresourcemanager.GetIamPolicyRequest{
			Options: &cloudresourcemanager.GetPolicyOptions{
				RequestedPolicyVersion: tpgiamresource.IamPolicyVersion,
			},
		}).Do()
	if err != nil {
		return "", err
	}

	p.Bindings = tpgiamresource.MergeBindings(append(p.Bindings, bindings...))
	_, err = config.NewResourceManagerClient(config.UserAgent).Projects.SetIamPolicy(pid,
		&cloudresourcemanager.SetIamPolicyRequest{
			Policy:     p,
			UpdateMask: "bindings,etag,auditConfigs",
		}).Do()
	if err != nil {
		return "", err
	}

	// Create a service account for project-1
	serviceAccountEmail := serviceAccountPrefix + service
	sa1, err := getOrCreateServiceAccount(config, pid, serviceAccountEmail)
	if err != nil {
		return "", err
	}

	// Add permissions to service accounts

	// Permission needed for user_project_override
	proj2ServiceUsageBinding := &cloudresourcemanager.Binding{
		Members: []string{fmt.Sprintf("serviceAccount:%s", sa1.Email)},
		Role:    "roles/serviceusage.serviceUsageConsumer",
	}

	// Admin permission for service
	proj2ServiceAdminBinding := &cloudresourcemanager.Binding{
		Members: []string{fmt.Sprintf("serviceAccount:%s", sa1.Email)},
		Role:    fmt.Sprintf("roles/%s.admin", service),
	}

	bindings = tpgiamresource.MergeBindings([]*cloudresourcemanager.Binding{proj2ServiceUsageBinding, proj2ServiceAdminBinding})

	// For KMS test only
	if service == "cloudkms" {
		proj2CryptoKeyBinding := &cloudresourcemanager.Binding{
			Members: []string{fmt.Sprintf("serviceAccount:%s", sa1.Email)},
			Role:    "roles/cloudkms.cryptoKeyEncrypter",
		}

		bindings = tpgiamresource.MergeBindings(append(bindings, proj2CryptoKeyBinding))
	}

	p, err = rmService.Projects.GetIamPolicy(p2,
		&cloudresourcemanager.GetIamPolicyRequest{
			Options: &cloudresourcemanager.GetPolicyOptions{
				RequestedPolicyVersion: tpgiamresource.IamPolicyVersion,
			},
		}).Do()
	if err != nil {
		return "", err
	}

	p.Bindings = tpgiamresource.MergeBindings(append(p.Bindings, bindings...))
	_, err = config.NewResourceManagerClient(config.UserAgent).Projects.SetIamPolicy(p2,
		&cloudresourcemanager.SetIamPolicyRequest{
			Policy:     p,
			UpdateMask: "bindings,etag,auditConfigs",
		}).Do()
	if err != nil {
		return "", err
	}

	// The token creator IAM API call returns success long before the policy is
	// actually usable. Wait a solid 2 minutes to ensure we can use it.
	time.Sleep(2 * time.Minute)

	iamCredsService := config.NewIamCredentialsClient(config.UserAgent)
	tokenRequest := &iamcredentials.GenerateAccessTokenRequest{
		Lifetime: "300s",
		Scope:    []string{"https://www.googleapis.com/auth/cloud-platform"},
	}
	atResp, err := iamCredsService.Projects.ServiceAccounts.GenerateAccessToken(fmt.Sprintf("projects/-/serviceAccounts/%s", sa1.Email), tokenRequest).Do()
	if err != nil {
		return "", err
	}

	accessToken := atResp.AccessToken

	return accessToken, nil
}

const sharedTagKeyPrefix = "tf-bootstrap-tagkey"

func BootstrapSharedTestTagKey(t *testing.T, testId string) string {
	org := envvar.GetTestOrgFromEnv(t)
	sharedTagKey := fmt.Sprintf("%s-%s", sharedTagKeyPrefix, testId)
	tagKeyName := fmt.Sprintf("%s/%s", org, sharedTagKey)

	config := BootstrapConfig(t)
	if config == nil {
		return ""
	}

	log.Printf("[DEBUG] Getting shared test tag key %q", sharedTagKey)
	getURL := fmt.Sprintf("%stagKeys/namespaced?name=%s", config.TagsBasePath, tagKeyName)
	_, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
		Config:    config,
		Method:    "GET",
		Project:   config.Project,
		RawURL:    getURL,
		UserAgent: config.UserAgent,
		Timeout:   2 * time.Minute,
	})
	if err != nil && transport_tpg.IsGoogleApiErrorWithCode(err, 403) {
		log.Printf("[DEBUG] TagKey %q not found, bootstrapping", sharedTagKey)
		tagKeyObj := map[string]interface{}{
			"parent":      "organizations/" + org,
			"shortName":   sharedTagKey,
			"description": "Bootstrapped tag key for Terraform Acceptance testing",
		}

		_, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
			Config:    config,
			Method:    "POST",
			Project:   config.Project,
			RawURL:    config.TagsBasePath + "tagKeys/",
			UserAgent: config.UserAgent,
			Body:      tagKeyObj,
			Timeout:   10 * time.Minute,
		})
		if err != nil {
			t.Fatalf("Error bootstrapping shared tag key %q: %s", sharedTagKey, err)
		}

		log.Printf("[DEBUG] Waiting for shared tag key creation to finish")
	}

	_, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
		Config:    config,
		Method:    "GET",
		Project:   config.Project,
		RawURL:    getURL,
		UserAgent: config.UserAgent,
		Timeout:   2 * time.Minute,
	})

	if err != nil {
		t.Fatalf("Error getting shared tag key %q: %s", sharedTagKey, err)
	}

	return sharedTagKey
}

const sharedTagValuePrefix = "tf-bootstrap-tagvalue"

func BootstrapSharedTestTagValue(t *testing.T, testId string, tagKey string) string {
	org := envvar.GetTestOrgFromEnv(t)
	sharedTagValue := fmt.Sprintf("%s-%s", sharedTagValuePrefix, testId)
	tagKeyName := fmt.Sprintf("%s/%s", org, tagKey)
	tagValueName := fmt.Sprintf("%s/%s", tagKeyName, sharedTagValue)

	config := BootstrapConfig(t)
	if config == nil {
		return ""
	}

	log.Printf("[DEBUG] Getting shared test tag value %q", sharedTagValue)
	getURL := fmt.Sprintf("%stagValues/namespaced?name=%s", config.TagsBasePath, tagValueName)
	_, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
		Config:    config,
		Method:    "GET",
		Project:   config.Project,
		RawURL:    getURL,
		UserAgent: config.UserAgent,
		Timeout:   2 * time.Minute,
	})
	if err != nil && transport_tpg.IsGoogleApiErrorWithCode(err, 403) {
		log.Printf("[DEBUG] TagValue %q not found, bootstrapping", sharedTagValue)
		log.Printf("[DEBUG] Fetching permanent id for tagkey %s", tagKeyName)
		tagKeyGetURL := fmt.Sprintf("%stagKeys/namespaced?name=%s", config.TagsBasePath, tagKeyName)
		tagKeyResponse, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
			Config:    config,
			Method:    "GET",
			Project:   config.Project,
			RawURL:    tagKeyGetURL,
			UserAgent: config.UserAgent,
			Timeout:   2 * time.Minute,
		})
		if err != nil {
			t.Fatalf("Error getting tag key id for %s : %s", tagKeyName, err)
		}
		tagKeyObj := map[string]interface{}{
			"parent":      tagKeyResponse["name"].(string),
			"shortName":   sharedTagValue,
			"description": "Bootstrapped tag value for Terraform Acceptance testing",
		}

		_, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
			Config:    config,
			Method:    "POST",
			Project:   config.Project,
			RawURL:    config.TagsBasePath + "tagValues/",
			UserAgent: config.UserAgent,
			Body:      tagKeyObj,
			Timeout:   10 * time.Minute,
		})
		if err != nil {
			t.Fatalf("Error bootstrapping shared tag value %q: %s", sharedTagValue, err)
		}

		log.Printf("[DEBUG] Waiting for shared tag value creation to finish")
	}

	_, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
		Config:    config,
		Method:    "GET",
		Project:   config.Project,
		RawURL:    getURL,
		UserAgent: config.UserAgent,
		Timeout:   2 * time.Minute,
	})

	if err != nil {
		t.Fatalf("Error getting shared tag value %q: %s", sharedTagValue, err)
	}

	return sharedTagValue
}
