# (c) cavaliba.com  - data/api - helper.py

import json
import pprint

import yaml
from django.conf import settings
from django.http import HttpResponse


class MyYamlDumper(yaml.SafeDumper):
    def write_line_break(self, data=None):
        super().write_line_break(data)
        if len(self.indents) < 2:
            super().write_line_break()


def helper():
    print("helped")


def get_cavctl_version():
    return getattr(settings, "CAVALIBA_CAVCTL_VERSION", "")


def send_ok():

    reply = {"status": "OK"}
    content = json.dumps(reply, indent=2, ensure_ascii=False).encode("utf8")
    content_type = "application/json; charset=utf-8"
    return HttpResponse(content, status=200, content_type=content_type)


def send_error(error, status):
    """generic error reply"""

    if error:
        reply = {"error": error}
    else:
        reply = {"error": "other"}

    content = json.dumps(reply, indent=2, ensure_ascii=False).encode("utf8")
    content_type = "application/json; charset=utf-8"
    return HttpResponse(content, status=status, content_type=content_type)


def send_not_found(error="not found"):
    return send_error(error, 404)


def send_not_implemented():
    return send_error("not implemented", 501)


def send_denied(error=None):
    return send_error(error, 401)


# ---


def get_page(request):
    """Return the optional ?page=<int> parameter (default: 1)."""
    try:
        return int(request.GET.get("page", 1))
    except Exception:
        return 1


def get_size(request):
    """Return the optional ?size=<int> parameter controlling page size (default: 10)."""
    # NEXT: move default size to option
    try:
        return int(request.GET.get("size", 10))
    except Exception:
        return 10


def get_expand(request):
    """Return the optional ?expand=<bool> parameter to include full UI detail (default: False)."""
    try:
        return bool(request.GET.get("expand", False))
    except Exception:
        return False


def get_refs(request):
    """Return the optional ?refs=<csv> parameter as a list of schema names to inline, or None."""
    raw = request.GET.get("refs", "").strip()
    if not raw:
        return None
    return [t.strip() for t in raw.split(",") if t.strip()]


def get_rev(request):
    """Return the optional ?rev=<int> parameter, or None if absent/invalid."""
    try:
        raw = request.GET.get("rev", None)
        if raw is None:
            return None
        return int(raw)
    except Exception:
        return None


def send_response(request, reply, status):

    # log(DEBUG, app="api", view="ping", action="GET", status="OK", data="")

    # Get output format from URL parameter 'o' (default: json)
    output_format = request.GET.get("o", "json").lower()

    if output_format == "yaml":
        content = yaml.dump(
            reply,
            allow_unicode=True,
            sort_keys=False,
            Dumper=MyYamlDumper,
            default_flow_style=False,
        )
        content_type = "application/x-yaml; charset=utf-8"
        return HttpResponse(content, status=status, content_type=content_type)

    elif output_format == "txt":
        content = pprint.pformat(reply, indent=2, width=80)
        content_type = "text/plain; charset=utf-8"
        return HttpResponse(content + "\n", status=status, content_type=content_type)

    else:
        # Default to JSON : no list if only one item
        if isinstance(reply, list) and len(reply) == 1:
            content = json.dumps(reply[0], indent=2, ensure_ascii=False).encode("utf8")
        else:
            content = json.dumps(reply, indent=2, ensure_ascii=False).encode("utf8")
        content_type = "application/json; charset=utf-8"
        return HttpResponse(content + b"\n", status=status, content_type=content_type)
