// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Code generated by protoc-gen-go_gapic. DO NOT EDIT.

package iap_test

import (
	"context"

	iap "cloud.google.com/go/iap/apiv1"
	"google.golang.org/api/iterator"
	iappb "google.golang.org/genproto/googleapis/cloud/iap/v1"
)

func ExampleNewIdentityAwareProxyOAuthClient() {
	ctx := context.Background()
	c, err := iap.NewIdentityAwareProxyOAuthClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}
	defer c.Close()

	// TODO: Use client.
	_ = c
}

func ExampleIdentityAwareProxyOAuthClient_ListBrands() {
	ctx := context.Background()
	c, err := iap.NewIdentityAwareProxyOAuthClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}
	defer c.Close()

	req := &iappb.ListBrandsRequest{
		// TODO: Fill request struct fields.
		// See https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/iap/v1#ListBrandsRequest.
	}
	resp, err := c.ListBrands(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIdentityAwareProxyOAuthClient_CreateBrand() {
	ctx := context.Background()
	c, err := iap.NewIdentityAwareProxyOAuthClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}
	defer c.Close()

	req := &iappb.CreateBrandRequest{
		// TODO: Fill request struct fields.
		// See https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/iap/v1#CreateBrandRequest.
	}
	resp, err := c.CreateBrand(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIdentityAwareProxyOAuthClient_GetBrand() {
	ctx := context.Background()
	c, err := iap.NewIdentityAwareProxyOAuthClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}
	defer c.Close()

	req := &iappb.GetBrandRequest{
		// TODO: Fill request struct fields.
		// See https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/iap/v1#GetBrandRequest.
	}
	resp, err := c.GetBrand(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIdentityAwareProxyOAuthClient_CreateIdentityAwareProxyClient() {
	ctx := context.Background()
	c, err := iap.NewIdentityAwareProxyOAuthClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}
	defer c.Close()

	req := &iappb.CreateIdentityAwareProxyClientRequest{
		// TODO: Fill request struct fields.
		// See https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/iap/v1#CreateIdentityAwareProxyClientRequest.
	}
	resp, err := c.CreateIdentityAwareProxyClient(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIdentityAwareProxyOAuthClient_ListIdentityAwareProxyClients() {
	ctx := context.Background()
	c, err := iap.NewIdentityAwareProxyOAuthClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}
	defer c.Close()

	req := &iappb.ListIdentityAwareProxyClientsRequest{
		// TODO: Fill request struct fields.
		// See https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/iap/v1#ListIdentityAwareProxyClientsRequest.
	}
	it := c.ListIdentityAwareProxyClients(ctx, req)
	for {
		resp, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			// TODO: Handle error.
		}
		// TODO: Use resp.
		_ = resp
	}
}

func ExampleIdentityAwareProxyOAuthClient_GetIdentityAwareProxyClient() {
	ctx := context.Background()
	c, err := iap.NewIdentityAwareProxyOAuthClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}
	defer c.Close()

	req := &iappb.GetIdentityAwareProxyClientRequest{
		// TODO: Fill request struct fields.
		// See https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/iap/v1#GetIdentityAwareProxyClientRequest.
	}
	resp, err := c.GetIdentityAwareProxyClient(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIdentityAwareProxyOAuthClient_ResetIdentityAwareProxyClientSecret() {
	ctx := context.Background()
	c, err := iap.NewIdentityAwareProxyOAuthClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}
	defer c.Close()

	req := &iappb.ResetIdentityAwareProxyClientSecretRequest{
		// TODO: Fill request struct fields.
		// See https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/iap/v1#ResetIdentityAwareProxyClientSecretRequest.
	}
	resp, err := c.ResetIdentityAwareProxyClientSecret(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIdentityAwareProxyOAuthClient_DeleteIdentityAwareProxyClient() {
	ctx := context.Background()
	c, err := iap.NewIdentityAwareProxyOAuthClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}
	defer c.Close()

	req := &iappb.DeleteIdentityAwareProxyClientRequest{
		// TODO: Fill request struct fields.
		// See https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/iap/v1#DeleteIdentityAwareProxyClientRequest.
	}
	err = c.DeleteIdentityAwareProxyClient(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
}
