# Code generated by stigmer-codegen. DO NOT EDIT.

from __future__ import annotations

from dataclasses import dataclass, field

import grpc

from ai.stigmer.iam.identityprovider.v1 import api_pb2
from ai.stigmer.iam.identityprovider.v1 import command_pb2_grpc
from ai.stigmer.iam.identityprovider.v1 import query_pb2_grpc
from ai.stigmer.iam.identityprovider.v1 import io_pb2
from ai.stigmer.iam.identityprovider.v1 import spec_pb2
from ai.stigmer.commons.apiresource import io_pb2 as apiresource_io_pb2
from ai.stigmer.commons.apiresource import metadata_pb2
from ai.stigmer.commons.apiresource.apiresourcekind import api_resource_kind_pb2

from ._errors import wrap_error
from ._types import DeleteResourceInput, ResourceRef


class IdentityProviderClient:
    """Provides operations on identityprovider resources."""

    def __init__(self, channel: grpc.Channel) -> None:
        self._command = command_pb2_grpc.IdentityProviderCommandControllerStub(channel)
        self._query = query_pb2_grpc.IdentityProviderQueryControllerStub(channel)

    def apply(self, input: IdentityProviderInput) -> api_pb2.IdentityProvider:
        try:
            return self._command.apply(input._to_proto())
        except grpc.RpcError as e:
            raise wrap_error(e) from e

    def create(self, input: IdentityProviderInput) -> api_pb2.IdentityProvider:
        try:
            return self._command.create(input._to_proto())
        except grpc.RpcError as e:
            raise wrap_error(e) from e

    def update(self, input: IdentityProviderInput) -> api_pb2.IdentityProvider:
        try:
            return self._command.update(input._to_proto())
        except grpc.RpcError as e:
            raise wrap_error(e) from e

    def delete(self, input: DeleteResourceInput) -> api_pb2.IdentityProvider:
        try:
            return self._command.delete(input._to_proto())
        except grpc.RpcError as e:
            raise wrap_error(e) from e

    def get(self, id: str) -> api_pb2.IdentityProvider:
        try:
            return self._query.get(apiresource_io_pb2.ApiResourceId(value=id))
        except grpc.RpcError as e:
            raise wrap_error(e) from e

    def get_by_reference(self, ref: ResourceRef) -> api_pb2.IdentityProvider:
        try:
            proto = ref._to_proto()
            proto.kind = api_resource_kind_pb2.identity_provider
            return self._query.getByReference(proto)
        except grpc.RpcError as e:
            raise wrap_error(e) from e


@dataclass
class IdentityProviderInput:
    """Input for creating or updating a IdentityProvider."""

    name: str
    org: str
    slug: str | None = None
    labels: dict[str, str] | None = None
    display_name: str = ""
    jwks_uri: str = ""
    allowed_issuers: list[str] = field(default_factory=list)
    expected_audience: str = ""
    rate_limit_budget: int = 0
    userinfo_endpoint: str = ""

    def _to_proto(self) -> api_pb2.IdentityProvider:
        spec = spec_pb2.IdentityProviderSpec(
            display_name=self.display_name,
            jwks_uri=self.jwks_uri,
            expected_audience=self.expected_audience,
            rate_limit_budget=self.rate_limit_budget,
            userinfo_endpoint=self.userinfo_endpoint,
        )
        if self.allowed_issuers:
            spec.allowed_issuers.extend(self.allowed_issuers)
        metadata = metadata_pb2.ApiResourceMetadata(
            name=self.name,
            org=self.org,
        )
        if self.slug:
            metadata.slug = self.slug
        if self.labels:
            metadata.labels.update(self.labels)
        return api_pb2.IdentityProvider(
            api_version="iam.stigmer.ai/v1",
            kind="IdentityProvider",
            metadata=metadata,
            spec=spec,
        )

