from __future__ import annotations

from typing import TYPE_CHECKING, Optional

from mockmesh.interceptors.azure.utils import _enc, _get_body
from mockmesh.interceptors.responses import FakeAzureResponse

if TYPE_CHECKING:
    from mockmesh.storage.manager import StorageManager


def handle_blob(
    sm: "StorageManager", parsed: dict, request: object,
    method: str, url: str, tpl: dict,
) -> Optional[FakeAzureResponse]:
    container = parsed["container"]
    blob_path = parsed["path"]

    if method == "PUT" and blob_path:
        raw    = _get_body(request)
        ct     = dict(getattr(request, "headers", {})).get("Content-Type", "application/octet-stream")
        stored = sm.az_blob_put(container, blob_path, raw, ct)
        status  = tpl.get("PUT", {}).get("status", 201)
        headers = dict(tpl.get("PUT", {}).get("headers", {}))
        headers["ETag"] = stored.get("ETag", '"mock"')
        return FakeAzureResponse(status, headers, b"")

    if method == "GET" and blob_path:
        obj = sm.az_blob_get(container, blob_path)
        if obj:
            hdr_tpl = dict(tpl.get("GET_headers", {}))
            headers = {
                **hdr_tpl,
                "Content-Type":   obj.get("ContentType", hdr_tpl.get("Content-Type", "application/octet-stream")),
                "ETag":           obj.get("ETag", hdr_tpl.get("ETag", '"mock"')),
                "Content-Length": str(obj.get("ContentLength", 0)),
            }
            return FakeAzureResponse(tpl.get("GET", {}).get("status", 200), headers, obj["Body"])

    if method == "GET" and not blob_path:
        items    = sm.blob.list_objects(sm._az_container(container), "")
        list_tpl = dict(tpl.get("GET_list", {"value": [], "nextLink": None}))
        item_tpl = dict(tpl.get("item_shape", {}))
        list_tpl["value"] = [
            {**item_tpl,
             "name": o.get("Key", o.get("key", "?")),
             "properties": {**item_tpl.get("properties", {}), "contentLength": o.get("Size", 0)}}
            for o in items
        ]
        return FakeAzureResponse(200, {"Content-Type": "application/json"}, _enc(list_tpl))

    if method == "DELETE" and blob_path:
        sm.az_blob_delete(container, blob_path)
        return FakeAzureResponse(tpl.get("DELETE", {}).get("status", 202), {}, b"")

    return None
