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

from __future__ import annotations

from dataclasses import dataclass

import grpc

from ai.stigmer.iam.iampolicy.v1 import api_pb2
from ai.stigmer.iam.iampolicy.v1 import command_pb2_grpc
from ai.stigmer.iam.iampolicy.v1 import query_pb2_grpc
from ai.stigmer.iam.iampolicy.v1 import io_pb2
from ai.stigmer.iam.iampolicy.v1 import spec_pb2
from ai.stigmer.commons.apiresource import metadata_pb2

from ._errors import wrap_error


class IamPolicyClient:
    """Provides operations on iampolicy resources."""

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

    def create(self, input: io_pb2.IamPolicySpec) -> api_pb2.IamPolicy:
        try:
            return self._command.create(input)
        except grpc.RpcError as e:
            raise wrap_error(e) from e

    def delete(self, input: io_pb2.IamPolicySpec) -> api_pb2.IamPolicy:
        try:
            return self._command.delete(input)
        except grpc.RpcError as e:
            raise wrap_error(e) from e

    def bootstrap_policy(self, input: io_pb2.IamPolicySpec) -> api_pb2.IamPolicy:
        try:
            return self._command.bootstrapPolicy(input)
        except grpc.RpcError as e:
            raise wrap_error(e) from e

    def cleanup_resource_policies(self, input: io_pb2.ApiResourceRef) -> None:
        try:
            self._command.cleanupResourcePolicies(input)
        except grpc.RpcError as e:
            raise wrap_error(e) from e

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

    def check_authorization(self, input: io_pb2.CheckAuthorizationInput) -> io_pb2.CheckAuthorizationResult:
        try:
            return self._query.checkAuthorization(input)
        except grpc.RpcError as e:
            raise wrap_error(e) from e

    def list_authorized_resource_ids(self, input: io_pb2.ListAuthorizedResourceIdsInput) -> io_pb2.AuthorizedResourceIdsList:
        try:
            return self._query.listAuthorizedResourceIds(input)
        except grpc.RpcError as e:
            raise wrap_error(e) from e

    def list_authorized_principal_ids(self, input: io_pb2.ListAuthorizedPrincipalIdsInput) -> io_pb2.AuthorizedPrincipalIdsList:
        try:
            return self._query.listAuthorizedPrincipalIds(input)
        except grpc.RpcError as e:
            raise wrap_error(e) from e


@dataclass
class IamPolicyInput:
    """Input for creating or updating a IamPolicy."""

    name: str
    org: str
    principal: ApiResourceRefInput | None
    resource: ApiResourceRefInput | None
    relation: str
    slug: str | None = None
    labels: dict[str, str] | None = None

    def _to_proto(self) -> api_pb2.IamPolicy:
        spec = spec_pb2.IamPolicySpec(
            relation=self.relation,
        )
        if self.principal is not None:
            spec.principal.CopyFrom(self.principal._to_proto())
        if self.resource is not None:
            spec.resource.CopyFrom(self.resource._to_proto())
        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.IamPolicy(
            api_version="iam.stigmer.ai/v1",
            kind="IamPolicy",
            metadata=metadata,
            spec=spec,
        )


@dataclass
class ApiResourceRefInput:
    """SDK input type for ApiResourceRef."""

    kind: str
    id: str
    relation: str = ""

    def _to_proto(self) -> spec_pb2.ApiResourceRef:
        msg = spec_pb2.ApiResourceRef(
            kind=self.kind,
            id=self.id,
            relation=self.relation,
        )
        return msg

