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

import (
	"context"

	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"
)

// KeyClient provides methods for managing Key resources of Yandex.Cloud IAM.
type KeyClient interface {
	KeyClientIterator
	Get(context.Context, *iam.GetKeyRequest, ...grpc.CallOption) (*iam.Key, error)
	List(context.Context, *iam.ListKeysRequest, ...grpc.CallOption) (*iam.ListKeysResponse, error)
	Create(context.Context, *iam.CreateKeyRequest, ...grpc.CallOption) (*iam.CreateKeyResponse, error)
	Update(context.Context, *iam.UpdateKeyRequest, ...grpc.CallOption) (*KeyUpdateOperation, error)
	Delete(context.Context, *iam.DeleteKeyRequest, ...grpc.CallOption) (*KeyDeleteOperation, error)
	ListOperations(context.Context, *iam.ListKeyOperationsRequest, ...grpc.CallOption) (*iam.ListKeyOperationsResponse, error)
}

var _ KeyClient = keyClient{}

type keyClient struct {
	connector transport.Connector
}

// NewKeyClient returns KeyClient implementation.
func NewKeyClient(connector transport.Connector) KeyClient {
	return keyClient{connector}
}

// Get is an operation of Yandex.Cloud IAM Key service.
func (c keyClient) Get(ctx context.Context, in *iam.GetKeyRequest, opts ...grpc.CallOption) (*iam.Key, error) {
	connection, err := c.connector.GetConnection(ctx, KeyGet, opts...)
	if err != nil {
		return nil, err
	}
	return iam.NewKeyServiceClient(connection).Get(ctx, in, opts...)
}

// List is an operation of Yandex.Cloud IAM Key service.
func (c keyClient) List(ctx context.Context, in *iam.ListKeysRequest, opts ...grpc.CallOption) (*iam.ListKeysResponse, error) {
	connection, err := c.connector.GetConnection(ctx, KeyList, opts...)
	if err != nil {
		return nil, err
	}
	return iam.NewKeyServiceClient(connection).List(ctx, in, opts...)
}

// Create is an operation of Yandex.Cloud IAM Key service.
func (c keyClient) Create(ctx context.Context, in *iam.CreateKeyRequest, opts ...grpc.CallOption) (*iam.CreateKeyResponse, error) {
	connection, err := c.connector.GetConnection(ctx, KeyCreate, opts...)
	if err != nil {
		return nil, err
	}
	return iam.NewKeyServiceClient(connection).Create(ctx, in, opts...)
}

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

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

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

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

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

// Update is an operation of Yandex.Cloud IAM Key service.
// It returns an object which should be used to monitor the operation state.
func (c keyClient) Update(ctx context.Context, in *iam.UpdateKeyRequest, opts ...grpc.CallOption) (*KeyUpdateOperation, error) {
	connection, err := c.connector.GetConnection(ctx, KeyUpdate, opts...)
	if err != nil {
		return nil, err
	}
	pb, err := iam.NewKeyServiceClient(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.UpdateKeyMetadata).GetKeyId()
		},
		MetadataType: (*iam.UpdateKeyMetadata)(nil),
		ResponseType: (*iam.Key)(nil),
	})
	if err != nil {
		return nil, err
	}
	return &KeyUpdateOperation{*op}, nil
}

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

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

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

// Wait polls the operation until it's done.
func (o *KeyDeleteOperation) 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 *KeyDeleteOperation) 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 Key service.
// It returns an object which should be used to monitor the operation state.
func (c keyClient) Delete(ctx context.Context, in *iam.DeleteKeyRequest, opts ...grpc.CallOption) (*KeyDeleteOperation, error) {
	connection, err := c.connector.GetConnection(ctx, KeyDelete, opts...)
	if err != nil {
		return nil, err
	}
	pb, err := iam.NewKeyServiceClient(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.DeleteKeyMetadata).GetKeyId()
		},
		MetadataType: (*iam.DeleteKeyMetadata)(nil),
		ResponseType: (*emptypb.Empty)(nil),
	})
	if err != nil {
		return nil, err
	}
	return &KeyDeleteOperation{*op}, nil
}

// ListOperations is an operation of Yandex.Cloud IAM Key service.
func (c keyClient) ListOperations(ctx context.Context, in *iam.ListKeyOperationsRequest, opts ...grpc.CallOption) (*iam.ListKeyOperationsResponse, error) {
	connection, err := c.connector.GetConnection(ctx, KeyListOperations, opts...)
	if err != nil {
		return nil, err
	}
	return iam.NewKeyServiceClient(connection).ListOperations(ctx, in, opts...)
}

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

var (
	KeyGet             = protoreflect.FullName("yandex.cloud.iam.v1.KeyService.Get")
	KeyList            = protoreflect.FullName("yandex.cloud.iam.v1.KeyService.List")
	KeyCreate          = protoreflect.FullName("yandex.cloud.iam.v1.KeyService.Create")
	KeyUpdate          = protoreflect.FullName("yandex.cloud.iam.v1.KeyService.Update")
	KeyDelete          = protoreflect.FullName("yandex.cloud.iam.v1.KeyService.Delete")
	KeyListOperations  = protoreflect.FullName("yandex.cloud.iam.v1.KeyService.ListOperations")
	KeyOperationPoller = protoreflect.FullName("yandex.cloud.operation.OperationService.Get")
)
