import logging
import warnings
from typing import Type

logger = logging.getLogger(__name__)


class IcatMetadataFutureWarning(FutureWarning):
    """Warning for upcoming changes in ICAT metadata."""


class IcatMetadataSerializationError(TypeError):
    """ICAT metadata serialization failed."""


class IcatMetadataValidationError(ValueError):
    """ICAT metadata validation error when strict-mode is ON."""


class IcatMetadataValidationWarning(IcatMetadataFutureWarning):
    """Used instead of IcatMetadataValidationError when strict-mode is OFF."""


class IcatMetadataDeprecatedWarning(IcatMetadataFutureWarning):
    """Warning for deprecated ICAT metadata fields."""


def warn(message: str, warning_type: Type[Warning]) -> None:
    """Log message and emit as warning."""
    # For humans to see
    logger.warning(message)

    # For client code the act upon (e.g. log in the e-logbook)
    warnings.warn(message, warning_type, stacklevel=2)


def invalid_warn_or_raise(message: str, strict: bool = False) -> None:
    if strict:
        raise IcatMetadataValidationError(message)
    warn(message, IcatMetadataValidationWarning)
