// Copyright 2020 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 irm_test

import (
	"context"

	irm "cloud.google.com/go/irm/apiv1alpha2"
	"google.golang.org/api/iterator"
	irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"
)

func ExampleNewIncidentClient() {
	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use client.
	_ = c
}

func ExampleIncidentClient_CreateIncident() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.CreateIncidentRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.CreateIncident(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIncidentClient_GetIncident() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.GetIncidentRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.GetIncident(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIncidentClient_SearchIncidents() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"
	// import "google.golang.org/api/iterator"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.SearchIncidentsRequest{
		// TODO: Fill request struct fields.
	}
	it := c.SearchIncidents(ctx, req)
	for {
		resp, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			// TODO: Handle error.
		}
		// TODO: Use resp.
		_ = resp
	}
}

func ExampleIncidentClient_UpdateIncident() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.UpdateIncidentRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.UpdateIncident(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIncidentClient_SearchSimilarIncidents() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"
	// import "google.golang.org/api/iterator"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.SearchSimilarIncidentsRequest{
		// TODO: Fill request struct fields.
	}
	it := c.SearchSimilarIncidents(ctx, req)
	for {
		resp, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			// TODO: Handle error.
		}
		// TODO: Use resp.
		_ = resp
	}
}

func ExampleIncidentClient_CreateAnnotation() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.CreateAnnotationRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.CreateAnnotation(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIncidentClient_ListAnnotations() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"
	// import "google.golang.org/api/iterator"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.ListAnnotationsRequest{
		// TODO: Fill request struct fields.
	}
	it := c.ListAnnotations(ctx, req)
	for {
		resp, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			// TODO: Handle error.
		}
		// TODO: Use resp.
		_ = resp
	}
}

func ExampleIncidentClient_CreateTag() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.CreateTagRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.CreateTag(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIncidentClient_DeleteTag() {
	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.DeleteTagRequest{
		// TODO: Fill request struct fields.
	}
	err = c.DeleteTag(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
}

func ExampleIncidentClient_ListTags() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"
	// import "google.golang.org/api/iterator"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.ListTagsRequest{
		// TODO: Fill request struct fields.
	}
	it := c.ListTags(ctx, req)
	for {
		resp, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			// TODO: Handle error.
		}
		// TODO: Use resp.
		_ = resp
	}
}

func ExampleIncidentClient_CreateSignal() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.CreateSignalRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.CreateSignal(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIncidentClient_SearchSignals() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"
	// import "google.golang.org/api/iterator"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.SearchSignalsRequest{
		// TODO: Fill request struct fields.
	}
	it := c.SearchSignals(ctx, req)
	for {
		resp, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			// TODO: Handle error.
		}
		// TODO: Use resp.
		_ = resp
	}
}

func ExampleIncidentClient_LookupSignal() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.LookupSignalRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.LookupSignal(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIncidentClient_GetSignal() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.GetSignalRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.GetSignal(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIncidentClient_UpdateSignal() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.UpdateSignalRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.UpdateSignal(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIncidentClient_EscalateIncident() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.EscalateIncidentRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.EscalateIncident(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIncidentClient_CreateArtifact() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.CreateArtifactRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.CreateArtifact(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIncidentClient_ListArtifacts() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"
	// import "google.golang.org/api/iterator"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.ListArtifactsRequest{
		// TODO: Fill request struct fields.
	}
	it := c.ListArtifacts(ctx, req)
	for {
		resp, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			// TODO: Handle error.
		}
		// TODO: Use resp.
		_ = resp
	}
}

func ExampleIncidentClient_UpdateArtifact() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.UpdateArtifactRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.UpdateArtifact(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIncidentClient_DeleteArtifact() {
	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.DeleteArtifactRequest{
		// TODO: Fill request struct fields.
	}
	err = c.DeleteArtifact(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
}

func ExampleIncidentClient_SendShiftHandoff() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.SendShiftHandoffRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.SendShiftHandoff(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIncidentClient_CreateSubscription() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.CreateSubscriptionRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.CreateSubscription(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIncidentClient_UpdateSubscription() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.UpdateSubscriptionRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.UpdateSubscription(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIncidentClient_ListSubscriptions() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"
	// import "google.golang.org/api/iterator"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.ListSubscriptionsRequest{
		// TODO: Fill request struct fields.
	}
	it := c.ListSubscriptions(ctx, req)
	for {
		resp, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			// TODO: Handle error.
		}
		// TODO: Use resp.
		_ = resp
	}
}

func ExampleIncidentClient_DeleteSubscription() {
	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.DeleteSubscriptionRequest{
		// TODO: Fill request struct fields.
	}
	err = c.DeleteSubscription(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
}

func ExampleIncidentClient_CreateIncidentRoleAssignment() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.CreateIncidentRoleAssignmentRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.CreateIncidentRoleAssignment(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIncidentClient_DeleteIncidentRoleAssignment() {
	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.DeleteIncidentRoleAssignmentRequest{
		// TODO: Fill request struct fields.
	}
	err = c.DeleteIncidentRoleAssignment(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
}

func ExampleIncidentClient_ListIncidentRoleAssignments() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"
	// import "google.golang.org/api/iterator"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.ListIncidentRoleAssignmentsRequest{
		// TODO: Fill request struct fields.
	}
	it := c.ListIncidentRoleAssignments(ctx, req)
	for {
		resp, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			// TODO: Handle error.
		}
		// TODO: Use resp.
		_ = resp
	}
}

func ExampleIncidentClient_RequestIncidentRoleHandover() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.RequestIncidentRoleHandoverRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.RequestIncidentRoleHandover(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIncidentClient_ConfirmIncidentRoleHandover() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.ConfirmIncidentRoleHandoverRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.ConfirmIncidentRoleHandover(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIncidentClient_ForceIncidentRoleHandover() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.ForceIncidentRoleHandoverRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.ForceIncidentRoleHandover(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

func ExampleIncidentClient_CancelIncidentRoleHandover() {
	// import irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"

	ctx := context.Background()
	c, err := irm.NewIncidentClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}

	req := &irmpb.CancelIncidentRoleHandoverRequest{
		// TODO: Fill request struct fields.
	}
	resp, err := c.CancelIncidentRoleHandover(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}
