"""Business-rule validators for the Article domain."""
from __future__ import annotations

from repo_core.base.validators import BaseValidator, ValidationError, ValidatorPipeline


class ArticleTitleValidator(BaseValidator):
    """Reject blank or overly-long article titles.

    Usage::

        validator = ArticleTitleValidator(max_length=255)
        clean_title = await validator.validate("  Hello  ")  # "Hello"
    """

    def __init__(self, max_length: int = 255) -> None:
        self._max = max_length

    async def validate(self, data: str) -> str:
        value = data.strip() if isinstance(data, str) else data
        if not value:
            raise ValidationError("Title cannot be blank.", field="title")
        if len(value) > self._max:
            raise ValidationError(
                f"Title must be at most {self._max} characters.", field="title"
            )
        return value


class ArticleBodyValidator(BaseValidator):
    """Ensure the article body is not empty.

    Usage::

        validator = ArticleBodyValidator()
        clean_body = await validator.validate("Some content")
    """

    async def validate(self, data: str) -> str:
        if not data or not data.strip():
            raise ValidationError("Body cannot be empty.", field="body")
        return data.strip()


def build_article_pipeline() -> ValidatorPipeline:
    """Return a ready-to-use pipeline that validates title then body.

    Usage::

        pipeline = build_article_pipeline()
        clean_title = await pipeline.validate(raw_title)
    """
    return ValidatorPipeline(ArticleTitleValidator(), ArticleBodyValidator())
