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

from __future__ import annotations

from dataclasses import dataclass

import grpc

from ai.stigmer.agentic.skill.v1 import api_pb2
from ai.stigmer.agentic.skill.v1 import command_pb2_grpc
from ai.stigmer.agentic.skill.v1 import query_pb2_grpc
from ai.stigmer.agentic.skill.v1 import io_pb2
from ai.stigmer.agentic.skill.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 ai.stigmer.search.v1 import query_pb2_grpc as search_query_pb2_grpc
from ai.stigmer.search.v1 import io_pb2 as search_io_pb2
from ai.stigmer.commons.rpc import pagination_pb2

from ._errors import wrap_error
from ._types import ListParams, ListResult, ResourceRef


class SkillClient:
    """Provides operations on skill resources."""

    def __init__(self, channel: grpc.Channel) -> None:
        self._command = command_pb2_grpc.SkillCommandControllerStub(channel)
        self._query = query_pb2_grpc.SkillQueryControllerStub(channel)
        self._search = search_query_pb2_grpc.SearchServiceStub(channel)

    def push(self, input: io_pb2.PushSkillRequest) -> api_pb2.Skill:
        try:
            return self._command.push(input)
        except grpc.RpcError as e:
            raise wrap_error(e) from e

    def push_from_execution_artifact(self, input: io_pb2.PushSkillFromExecutionArtifactRequest) -> api_pb2.Skill:
        try:
            return self._command.pushFromExecutionArtifact(input)
        except grpc.RpcError as e:
            raise wrap_error(e) from e

    def update_visibility(self, input: io_pb2.UpdateVisibilityInput) -> api_pb2.Skill:
        try:
            return self._command.updateVisibility(input)
        except grpc.RpcError as e:
            raise wrap_error(e) from e

    def delete(self, id: str) -> api_pb2.Skill:
        try:
            return self._command.delete(io_pb2.SkillId(value=id))
        except grpc.RpcError as e:
            raise wrap_error(e) from e

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

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

    def get_artifact(self, input: io_pb2.GetArtifactRequest) -> io_pb2.GetArtifactResponse:
        try:
            return self._query.getArtifact(input)
        except grpc.RpcError as e:
            raise wrap_error(e) from e

    def list(self, params: ListParams) -> ListResult:
        try:
            req = search_io_pb2.SearchRequest(
                kinds=[api_resource_kind_pb2.ApiResourceKind.skill],
                query=params.query,
                org=params.org,
                exclude_public=params.exclude_public,
            )
            if params.page is not None:
                req.page.CopyFrom(pagination_pb2.PageInfo(
                    num=params.page.num,
                    size=params.page.size,
                ))
            resp = self._search.search(req)
            return ListResult(
                entries=list(resp.entries),
                total_count=resp.total_count,
                total_pages=resp.total_pages,
            )
        except grpc.RpcError as e:
            raise wrap_error(e) from e


@dataclass
class SkillInput:
    """Input for creating or updating a Skill."""

    name: str
    org: str
    slug: str | None = None
    labels: dict[str, str] | None = None
    skill_md: str = ""
    tag: str = ""
    description: str = ""

    def _to_proto(self) -> api_pb2.Skill:
        spec = spec_pb2.SkillSpec(
            skill_md=self.skill_md,
            tag=self.tag,
            description=self.description,
        )
        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.Skill(
            api_version="agentic.stigmer.ai/v1",
            kind="Skill",
            metadata=metadata,
            spec=spec,
        )

