// Code generated by sdkgen-v2. DO NOT EDIT.
package iamsdk

import (
	"context"

	access "github.com/yandex-cloud/go-genproto/yandex/cloud/access"
	iam "github.com/yandex-cloud/go-genproto/yandex/cloud/iam/v1"
	operation "github.com/yandex-cloud/go-genproto/yandex/cloud/operation"
	sdkop "github.com/yandex-cloud/go-sdk/v2/pkg/operation"
	"github.com/yandex-cloud/go-sdk/v2/pkg/transport"
	"google.golang.org/grpc"
	proto "google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/reflect/protoreflect"
	emptypb "google.golang.org/protobuf/types/known/emptypb"
)

// ServiceAccountClient provides methods for managing ServiceAccount resources of Yandex.Cloud IAM.
type ServiceAccountClient interface {
	ServiceAccountClientIterator
	Get(context.Context, *iam.GetServiceAccountRequest, ...grpc.CallOption) (*iam.ServiceAccount, error)
	List(context.Context, *iam.ListServiceAccountsRequest, ...grpc.CallOption) (*iam.ListServiceAccountsResponse, error)
	Create(context.Context, *iam.CreateServiceAccountRequest, ...grpc.CallOption) (*ServiceAccountCreateOperation, error)
	Update(context.Context, *iam.UpdateServiceAccountRequest, ...grpc.CallOption) (*ServiceAccountUpdateOperation, error)
	Delete(context.Context, *iam.DeleteServiceAccountRequest, ...grpc.CallOption) (*ServiceAccountDeleteOperation, error)
	ListAccessBindings(context.Context, *access.ListAccessBindingsRequest, ...grpc.CallOption) (*access.ListAccessBindingsResponse, error)
	SetAccessBindings(context.Context, *access.SetAccessBindingsRequest, ...grpc.CallOption) (*ServiceAccountSetAccessBindingsOperation, error)
	UpdateAccessBindings(context.Context, *access.UpdateAccessBindingsRequest, ...grpc.CallOption) (*ServiceAccountUpdateAccessBindingsOperation, error)
	ListOperations(context.Context, *iam.ListServiceAccountOperationsRequest, ...grpc.CallOption) (*iam.ListServiceAccountOperationsResponse, error)
}

var _ ServiceAccountClient = serviceAccountClient{}

type serviceAccountClient struct {
	connector transport.Connector
}

// NewServiceAccountClient returns ServiceAccountClient implementation.
func NewServiceAccountClient(connector transport.Connector) ServiceAccountClient {
	return serviceAccountClient{connector}
}

// Get is an operation of Yandex.Cloud IAM ServiceAccount service.
func (c serviceAccountClient) Get(ctx context.Context, in *iam.GetServiceAccountRequest, opts ...grpc.CallOption) (*iam.ServiceAccount, error) {
	connection, err := c.connector.GetConnection(ctx, ServiceAccountGet, opts...)
	if err != nil {
		return nil, err
	}
	return iam.NewServiceAccountServiceClient(connection).Get(ctx, in, opts...)
}

// List is an operation of Yandex.Cloud IAM ServiceAccount service.
func (c serviceAccountClient) List(ctx context.Context, in *iam.ListServiceAccountsRequest, opts ...grpc.CallOption) (*iam.ListServiceAccountsResponse, error) {
	connection, err := c.connector.GetConnection(ctx, ServiceAccountList, opts...)
	if err != nil {
		return nil, err
	}
	return iam.NewServiceAccountServiceClient(connection).List(ctx, in, opts...)
}

// ServiceAccountCreateOperation is used to monitor the state of Create operations.
type ServiceAccountCreateOperation struct {
	sdkop.Operation
}

// Metadata retrieves the operation metadata.
func (o *ServiceAccountCreateOperation) Metadata() *iam.CreateServiceAccountMetadata {
	return o.Operation.Metadata().(*iam.CreateServiceAccountMetadata)
}

// Response retrieves the operation response.
func (o *ServiceAccountCreateOperation) Response() *iam.ServiceAccount {
	return o.Operation.Response().(*iam.ServiceAccount)
}

// Wait polls the operation until it's done.
func (o *ServiceAccountCreateOperation) Wait(ctx context.Context, opts ...grpc.CallOption) (*iam.ServiceAccount, error) {
	abstract, err := o.Operation.Wait(ctx, opts...)
	response, _ := abstract.(*iam.ServiceAccount)
	return response, err
}

// WaitInterval polls the operation until it's done with custom interval.
func (o *ServiceAccountCreateOperation) WaitInterval(ctx context.Context, pollInterval sdkop.PollIntervalFunc, opts ...grpc.CallOption) (*iam.ServiceAccount, error) {
	abstract, err := o.Operation.WaitInterval(ctx, pollInterval, opts...)
	response, _ := abstract.(*iam.ServiceAccount)
	return response, err
}

// Create is an operation of Yandex.Cloud IAM ServiceAccount service.
// It returns an object which should be used to monitor the operation state.
func (c serviceAccountClient) Create(ctx context.Context, in *iam.CreateServiceAccountRequest, opts ...grpc.CallOption) (*ServiceAccountCreateOperation, error) {
	connection, err := c.connector.GetConnection(ctx, ServiceAccountCreate, opts...)
	if err != nil {
		return nil, err
	}
	pb, err := iam.NewServiceAccountServiceClient(connection).Create(ctx, in, opts...)
	if err != nil {
		return nil, err
	}
	op, err := sdkop.NewOperation(pb, &sdkop.Concretization{
		Poll: c.pollOperation,
		GetResourceID: func(metadata proto.Message) string {
			return metadata.(*iam.CreateServiceAccountMetadata).GetServiceAccountId()
		},
		MetadataType: (*iam.CreateServiceAccountMetadata)(nil),
		ResponseType: (*iam.ServiceAccount)(nil),
	})
	if err != nil {
		return nil, err
	}
	return &ServiceAccountCreateOperation{*op}, nil
}

// ServiceAccountUpdateOperation is used to monitor the state of Update operations.
type ServiceAccountUpdateOperation struct {
	sdkop.Operation
}

// Metadata retrieves the operation metadata.
func (o *ServiceAccountUpdateOperation) Metadata() *iam.UpdateServiceAccountMetadata {
	return o.Operation.Metadata().(*iam.UpdateServiceAccountMetadata)
}

// Response retrieves the operation response.
func (o *ServiceAccountUpdateOperation) Response() *iam.ServiceAccount {
	return o.Operation.Response().(*iam.ServiceAccount)
}

// Wait polls the operation until it's done.
func (o *ServiceAccountUpdateOperation) Wait(ctx context.Context, opts ...grpc.CallOption) (*iam.ServiceAccount, error) {
	abstract, err := o.Operation.Wait(ctx, opts...)
	response, _ := abstract.(*iam.ServiceAccount)
	return response, err
}

// WaitInterval polls the operation until it's done with custom interval.
func (o *ServiceAccountUpdateOperation) WaitInterval(ctx context.Context, pollInterval sdkop.PollIntervalFunc, opts ...grpc.CallOption) (*iam.ServiceAccount, error) {
	abstract, err := o.Operation.WaitInterval(ctx, pollInterval, opts...)
	response, _ := abstract.(*iam.ServiceAccount)
	return response, err
}

// Update is an operation of Yandex.Cloud IAM ServiceAccount service.
// It returns an object which should be used to monitor the operation state.
func (c serviceAccountClient) Update(ctx context.Context, in *iam.UpdateServiceAccountRequest, opts ...grpc.CallOption) (*ServiceAccountUpdateOperation, error) {
	connection, err := c.connector.GetConnection(ctx, ServiceAccountUpdate, opts...)
	if err != nil {
		return nil, err
	}
	pb, err := iam.NewServiceAccountServiceClient(connection).Update(ctx, in, opts...)
	if err != nil {
		return nil, err
	}
	op, err := sdkop.NewOperation(pb, &sdkop.Concretization{
		Poll: c.pollOperation,
		GetResourceID: func(metadata proto.Message) string {
			return metadata.(*iam.UpdateServiceAccountMetadata).GetServiceAccountId()
		},
		MetadataType: (*iam.UpdateServiceAccountMetadata)(nil),
		ResponseType: (*iam.ServiceAccount)(nil),
	})
	if err != nil {
		return nil, err
	}
	return &ServiceAccountUpdateOperation{*op}, nil
}

// ServiceAccountDeleteOperation is used to monitor the state of Delete operations.
type ServiceAccountDeleteOperation struct {
	sdkop.Operation
}

// Metadata retrieves the operation metadata.
func (o *ServiceAccountDeleteOperation) Metadata() *iam.DeleteServiceAccountMetadata {
	return o.Operation.Metadata().(*iam.DeleteServiceAccountMetadata)
}

// Response retrieves the operation response.
func (o *ServiceAccountDeleteOperation) Response() *emptypb.Empty {
	return o.Operation.Response().(*emptypb.Empty)
}

// Wait polls the operation until it's done.
func (o *ServiceAccountDeleteOperation) Wait(ctx context.Context, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	abstract, err := o.Operation.Wait(ctx, opts...)
	response, _ := abstract.(*emptypb.Empty)
	return response, err
}

// WaitInterval polls the operation until it's done with custom interval.
func (o *ServiceAccountDeleteOperation) WaitInterval(ctx context.Context, pollInterval sdkop.PollIntervalFunc, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	abstract, err := o.Operation.WaitInterval(ctx, pollInterval, opts...)
	response, _ := abstract.(*emptypb.Empty)
	return response, err
}

// Delete is an operation of Yandex.Cloud IAM ServiceAccount service.
// It returns an object which should be used to monitor the operation state.
func (c serviceAccountClient) Delete(ctx context.Context, in *iam.DeleteServiceAccountRequest, opts ...grpc.CallOption) (*ServiceAccountDeleteOperation, error) {
	connection, err := c.connector.GetConnection(ctx, ServiceAccountDelete, opts...)
	if err != nil {
		return nil, err
	}
	pb, err := iam.NewServiceAccountServiceClient(connection).Delete(ctx, in, opts...)
	if err != nil {
		return nil, err
	}
	op, err := sdkop.NewOperation(pb, &sdkop.Concretization{
		Poll: c.pollOperation,
		GetResourceID: func(metadata proto.Message) string {
			return metadata.(*iam.DeleteServiceAccountMetadata).GetServiceAccountId()
		},
		MetadataType: (*iam.DeleteServiceAccountMetadata)(nil),
		ResponseType: (*emptypb.Empty)(nil),
	})
	if err != nil {
		return nil, err
	}
	return &ServiceAccountDeleteOperation{*op}, nil
}

// ListAccessBindings is an operation of Yandex.Cloud IAM ServiceAccount service.
func (c serviceAccountClient) ListAccessBindings(ctx context.Context, in *access.ListAccessBindingsRequest, opts ...grpc.CallOption) (*access.ListAccessBindingsResponse, error) {
	connection, err := c.connector.GetConnection(ctx, ServiceAccountListAccessBindings, opts...)
	if err != nil {
		return nil, err
	}
	return iam.NewServiceAccountServiceClient(connection).ListAccessBindings(ctx, in, opts...)
}

// ServiceAccountSetAccessBindingsOperation is used to monitor the state of SetAccessBindings operations.
type ServiceAccountSetAccessBindingsOperation struct {
	sdkop.Operation
}

// Metadata retrieves the operation metadata.
func (o *ServiceAccountSetAccessBindingsOperation) Metadata() *access.SetAccessBindingsMetadata {
	return o.Operation.Metadata().(*access.SetAccessBindingsMetadata)
}

// Response retrieves the operation response.
func (o *ServiceAccountSetAccessBindingsOperation) Response() *access.AccessBindingsOperationResult {
	return o.Operation.Response().(*access.AccessBindingsOperationResult)
}

// Wait polls the operation until it's done.
func (o *ServiceAccountSetAccessBindingsOperation) Wait(ctx context.Context, opts ...grpc.CallOption) (*access.AccessBindingsOperationResult, error) {
	abstract, err := o.Operation.Wait(ctx, opts...)
	response, _ := abstract.(*access.AccessBindingsOperationResult)
	return response, err
}

// WaitInterval polls the operation until it's done with custom interval.
func (o *ServiceAccountSetAccessBindingsOperation) WaitInterval(ctx context.Context, pollInterval sdkop.PollIntervalFunc, opts ...grpc.CallOption) (*access.AccessBindingsOperationResult, error) {
	abstract, err := o.Operation.WaitInterval(ctx, pollInterval, opts...)
	response, _ := abstract.(*access.AccessBindingsOperationResult)
	return response, err
}

// SetAccessBindings is an operation of Yandex.Cloud IAM ServiceAccount service.
// It returns an object which should be used to monitor the operation state.
func (c serviceAccountClient) SetAccessBindings(ctx context.Context, in *access.SetAccessBindingsRequest, opts ...grpc.CallOption) (*ServiceAccountSetAccessBindingsOperation, error) {
	connection, err := c.connector.GetConnection(ctx, ServiceAccountSetAccessBindings, opts...)
	if err != nil {
		return nil, err
	}
	pb, err := iam.NewServiceAccountServiceClient(connection).SetAccessBindings(ctx, in, opts...)
	if err != nil {
		return nil, err
	}
	op, err := sdkop.NewOperation(pb, &sdkop.Concretization{
		Poll:         c.pollOperation,
		MetadataType: (*access.SetAccessBindingsMetadata)(nil),
		ResponseType: (*access.AccessBindingsOperationResult)(nil),
	})
	if err != nil {
		return nil, err
	}
	return &ServiceAccountSetAccessBindingsOperation{*op}, nil
}

// ServiceAccountUpdateAccessBindingsOperation is used to monitor the state of UpdateAccessBindings operations.
type ServiceAccountUpdateAccessBindingsOperation struct {
	sdkop.Operation
}

// Metadata retrieves the operation metadata.
func (o *ServiceAccountUpdateAccessBindingsOperation) Metadata() *access.UpdateAccessBindingsMetadata {
	return o.Operation.Metadata().(*access.UpdateAccessBindingsMetadata)
}

// Response retrieves the operation response.
func (o *ServiceAccountUpdateAccessBindingsOperation) Response() *access.AccessBindingsOperationResult {
	return o.Operation.Response().(*access.AccessBindingsOperationResult)
}

// Wait polls the operation until it's done.
func (o *ServiceAccountUpdateAccessBindingsOperation) Wait(ctx context.Context, opts ...grpc.CallOption) (*access.AccessBindingsOperationResult, error) {
	abstract, err := o.Operation.Wait(ctx, opts...)
	response, _ := abstract.(*access.AccessBindingsOperationResult)
	return response, err
}

// WaitInterval polls the operation until it's done with custom interval.
func (o *ServiceAccountUpdateAccessBindingsOperation) WaitInterval(ctx context.Context, pollInterval sdkop.PollIntervalFunc, opts ...grpc.CallOption) (*access.AccessBindingsOperationResult, error) {
	abstract, err := o.Operation.WaitInterval(ctx, pollInterval, opts...)
	response, _ := abstract.(*access.AccessBindingsOperationResult)
	return response, err
}

// UpdateAccessBindings is an operation of Yandex.Cloud IAM ServiceAccount service.
// It returns an object which should be used to monitor the operation state.
func (c serviceAccountClient) UpdateAccessBindings(ctx context.Context, in *access.UpdateAccessBindingsRequest, opts ...grpc.CallOption) (*ServiceAccountUpdateAccessBindingsOperation, error) {
	connection, err := c.connector.GetConnection(ctx, ServiceAccountUpdateAccessBindings, opts...)
	if err != nil {
		return nil, err
	}
	pb, err := iam.NewServiceAccountServiceClient(connection).UpdateAccessBindings(ctx, in, opts...)
	if err != nil {
		return nil, err
	}
	op, err := sdkop.NewOperation(pb, &sdkop.Concretization{
		Poll:         c.pollOperation,
		MetadataType: (*access.UpdateAccessBindingsMetadata)(nil),
		ResponseType: (*access.AccessBindingsOperationResult)(nil),
	})
	if err != nil {
		return nil, err
	}
	return &ServiceAccountUpdateAccessBindingsOperation{*op}, nil
}

// ListOperations is an operation of Yandex.Cloud IAM ServiceAccount service.
func (c serviceAccountClient) ListOperations(ctx context.Context, in *iam.ListServiceAccountOperationsRequest, opts ...grpc.CallOption) (*iam.ListServiceAccountOperationsResponse, error) {
	connection, err := c.connector.GetConnection(ctx, ServiceAccountListOperations, opts...)
	if err != nil {
		return nil, err
	}
	return iam.NewServiceAccountServiceClient(connection).ListOperations(ctx, in, opts...)
}

// pollOperation returns the current state of the polled operation.
func (c serviceAccountClient) pollOperation(ctx context.Context, operationId string, opts ...grpc.CallOption) (sdkop.YCOperation, error) {
	connection, err := c.connector.GetConnection(ctx, ServiceAccountOperationPoller, opts...)
	if err != nil {
		return nil, err
	}
	return operation.NewOperationServiceClient(connection).Get(ctx, &operation.GetOperationRequest{OperationId: operationId}, opts...)
}

var (
	ServiceAccountGet                  = protoreflect.FullName("yandex.cloud.iam.v1.ServiceAccountService.Get")
	ServiceAccountList                 = protoreflect.FullName("yandex.cloud.iam.v1.ServiceAccountService.List")
	ServiceAccountCreate               = protoreflect.FullName("yandex.cloud.iam.v1.ServiceAccountService.Create")
	ServiceAccountUpdate               = protoreflect.FullName("yandex.cloud.iam.v1.ServiceAccountService.Update")
	ServiceAccountDelete               = protoreflect.FullName("yandex.cloud.iam.v1.ServiceAccountService.Delete")
	ServiceAccountListAccessBindings   = protoreflect.FullName("yandex.cloud.iam.v1.ServiceAccountService.ListAccessBindings")
	ServiceAccountSetAccessBindings    = protoreflect.FullName("yandex.cloud.iam.v1.ServiceAccountService.SetAccessBindings")
	ServiceAccountUpdateAccessBindings = protoreflect.FullName("yandex.cloud.iam.v1.ServiceAccountService.UpdateAccessBindings")
	ServiceAccountListOperations       = protoreflect.FullName("yandex.cloud.iam.v1.ServiceAccountService.ListOperations")
	ServiceAccountOperationPoller      = protoreflect.FullName("yandex.cloud.operation.OperationService.Get")
)
