"""api.__init__
"""
from flask_json import as_json
from flask import Blueprint
from flask import request, g
from flask_login import current_user
from app import db
from app.scodoc import sco_utils as scu
from app.scodoc.sco_exceptions import AccessDenied, ScoException
from app.scodoc.sco_permissions import Permission

api_bp = Blueprint("api", __name__)
api_web_bp = Blueprint("apiweb", __name__)

# HTTP ERROR STATUS
API_CLIENT_ERROR = 400  # erreur dans les paramètres fournis par le client


@api_bp.errorhandler(ScoException)
@api_web_bp.errorhandler(ScoException)
@api_bp.errorhandler(404)
def api_error_handler(e):
    "erreurs API => json"
    return scu.json_error(404, message=str(e))


@api_bp.errorhandler(AccessDenied)
@api_web_bp.errorhandler(AccessDenied)
def permission_denied_error_handler(exc):
    """
    Renvoie message d'erreur pour l'erreur 403
    """
    return scu.json_error(
        403, f"operation non autorisee ({exc.args[0] if exc.args else ''})"
    )


def requested_format(default_format="json", allowed_formats=None):
    """Extract required format from query string.
    * default value is json. A list of allowed formats may be provided
    (['json'] considered if not provided).
    * if the required format is not in allowed list, returns None.

    NB: if json in not in allowed_formats, format specification is mandatory.
    """
    format_type = request.args.get("format", default_format)
    if format_type in (allowed_formats or ["json"]):
        return format_type
    return None


@as_json
def get_model_api_object(
    model_cls: db.Model,
    model_id: int,
    join_cls: db.Model = None,
    restrict: bool | None = None,
):
    """
    Retourne une réponse contenant la représentation api de l'objet "Model[model_id]"

    Filtrage du département en fonction d'une classe de jointure (eg: Identite, Formsemestre) -> join_cls

    exemple d'utilisation : fonction "justificatif()" -> app/api/justificatifs.py

    L'agument restrict est passé to_dict, est signale que l'on veut une version restreinte
    (sans données personnelles, ou sans informations sur le justificatif d'absence)
    """
    query = model_cls.query.filter_by(id=model_id)
    if g.scodoc_dept and join_cls is not None:
        query = query.join(join_cls).filter_by(dept_id=g.scodoc_dept_id)
    unique: model_cls = query.first()

    if unique is None:
        return scu.json_error(
            404,
            message=f"{model_cls.__name__} inexistant(e)",
        )
    if restrict is None:
        return unique.to_dict(format_api=True)
    return unique.to_dict(format_api=True, restrict=restrict)


from app.api import tokens
from app.api import (
    assiduites,
    billets_absences,
    departements,
    etudiants,
    evaluations,
    formations,
    formsemestres,
    jury,
    justificatifs,
    logos,
    moduleimpl,
    partitions,
    semset,
    users,
)