"""Explicitly promote a small set of workspace files to user-facing artifacts."""
from __future__ import annotations

from pathlib import Path

from core.artifacts import (
    MAX_ARTIFACTS_PER_MESSAGE,
    ArtifactPathError,
    ArtifactRef,
    ToolExecutionResult,
    resolve_artifact_path,
)

from .base import Tool


class PublishArtifactsTool(Tool):
    name = "publish_artifacts"
    description = (
        "Publish a small set of final deliverable files to the chat. Ordinary source, "
        "temporary, intermediate, and project support files should stay in the file panel "
        "and must not be published. Paths are relative to the current task working directory."
    )
    parameters = {
        "type": "object",
        "properties": {
            "artifacts": {
                "type": "array",
                "minItems": 1,
                "maxItems": MAX_ARTIFACTS_PER_MESSAGE,
                "items": {
                    "type": "object",
                    "properties": {
                        "path": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 1000,
                            "description": "File path relative to the current task working directory.",
                        },
                        "label": {
                            "type": "string",
                            "maxLength": 120,
                            "description": "Optional short user-facing label.",
                        },
                    },
                    "required": ["path"],
                },
            }
        },
        "required": ["artifacts"],
    }

    def __init__(self, working_dir: Path, **kwargs) -> None:
        super().__init__(**kwargs)
        self.working_dir = Path(working_dir)

    def execute(self, artifacts: list[dict]) -> ToolExecutionResult | str:
        if not isinstance(artifacts, list) or not artifacts:
            return "[Error] artifacts must be a non-empty list"
        if len(artifacts) > MAX_ARTIFACTS_PER_MESSAGE:
            return f"[Error] at most {MAX_ARTIFACTS_PER_MESSAGE} artifacts may be published at once"
        if self.user_root is None:
            return "[Error] publish_artifacts requires a user workspace"

        refs: list[ArtifactRef] = []
        seen: set[str] = set()
        for item in artifacts:
            if not isinstance(item, dict):
                return "[Error] every artifact must be an object with path and optional label"
            try:
                raw_path = str(item.get("path") or "")
                if len(raw_path) > 1000:
                    return "[Error] artifact path is too long"
                label = str(item.get("label") or "").strip()
                if len(label) > 120:
                    return "[Error] artifact label is too long"
                _, rel = resolve_artifact_path(
                    raw_path,
                    working_dir=self.working_dir,
                    user_root=self.user_root,
                    require_file=True,
                    allow_legacy_user_relative=False,
                )
            except ArtifactPathError as exc:
                return f"[Error] cannot publish artifact: {exc}"
            if rel in seen:
                continue
            seen.add(rel)
            refs.append(ArtifactRef(path=rel, label=label))

        names = ", ".join(ref.label or ref.path for ref in refs)
        return ToolExecutionResult(
            content=f"[OK] published {len(refs)} artifact(s): {names}",
            artifacts=tuple(refs),
        )
