# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

import json
import logging
import re
from http import HTTPStatus
from http.server import BaseHTTPRequestHandler
from typing import Any, Dict, List, Optional, Tuple
from urllib.parse import parse_qs

from .backends import NbdBackend, create_backend
from .config import TransferRegistry
from .constants import CHUNK_SIZE, MAX_PARALLEL_READS, MAX_PARALLEL_WRITES, MAX_PATCH_JSON_SIZE
from .util import is_fallback_dirty_response, json_bytes, now_s


class Handler(BaseHTTPRequestHandler):
    """
    HTTP request handler for the image server.

    Routing, HTTP parsing, and response formatting live here.
    All backend I/O is delegated to ImageBackend implementations via the
    create_backend() factory.

    Class-level attribute _registry is injected
    by the server at startup (see server.py / make_handler()).
    """

    server_version = "cloudstack-image-server/1.0"
    protocol_version = "HTTP/1.1"

    _registry: TransferRegistry

    _CONTENT_RANGE_RE = re.compile(r"^bytes\s+(\d+)-(\d+)/(?:\*|\d+)$")

    def log_message(self, fmt: str, *args: Any) -> None:
        logging.debug("%s - - %s", self.client_address[0], fmt % args)

    # ------------------------------------------------------------------
    # Response helpers
    # ------------------------------------------------------------------

    def _send_imageio_headers(
        self, allowed_methods: Optional[str] = None
    ) -> None:
        if allowed_methods is None:
            allowed_methods = "GET, PUT, OPTIONS"
        self.send_header("Access-Control-Allow-Methods", allowed_methods)
        self.send_header("Accept-Ranges", "bytes")

    def _send_json(
        self,
        status: int,
        obj: Any,
        allowed_methods: Optional[str] = None,
    ) -> None:
        body = json_bytes(obj)
        self.send_response(status)
        self._send_imageio_headers(allowed_methods)
        self.send_header("Content-Type", "application/json")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        try:
            self.wfile.write(body)
        except BrokenPipeError:
            logging.error(
                "HTTP response write failure status=%s method=%s path=%s err=%s",
                int(status),
                self.command,
                self.path,
                "client disconnected",
            )

    def _send_error_json(self, status: int, message: str) -> None:
        logging.error(
            "HTTP failure status=%s method=%s path=%s message=%s",
            int(status),
            self.command,
            self.path,
            message,
        )
        self._send_json(status, {"error": message})

    def _send_range_not_satisfiable(self, size: int) -> None:
        logging.error(
            "HTTP failure status=%s method=%s path=%s message=%s size=%s",
            int(HTTPStatus.REQUESTED_RANGE_NOT_SATISFIABLE),
            self.command,
            self.path,
            "range not satisfiable",
            size,
        )
        self.send_response(HTTPStatus.REQUESTED_RANGE_NOT_SATISFIABLE)
        self._send_imageio_headers()
        self.send_header("Content-Type", "application/json")
        self.send_header("Content-Range", f"bytes */{size}")
        body = json_bytes({"error": "range not satisfiable"})
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        try:
            self.wfile.write(body)
        except BrokenPipeError:
            logging.error(
                "HTTP response write failure status=%s method=%s path=%s err=%s",
                int(HTTPStatus.REQUESTED_RANGE_NOT_SATISFIABLE),
                self.command,
                self.path,
                "client disconnected",
            )

    # ------------------------------------------------------------------
    # Parsing helpers
    # ------------------------------------------------------------------

    def _parse_single_range(self, range_header: str, size: int) -> Tuple[int, int]:
        """
        Parse a single HTTP byte range (RFC 7233) and return (start, end_inclusive).
        Raises ValueError for invalid headers.
        """
        if size < 0:
            raise ValueError("invalid size")
        if not range_header:
            raise ValueError("empty Range")
        if "," in range_header:
            raise ValueError("multiple ranges not supported")

        prefix = "bytes="
        if not range_header.startswith(prefix):
            raise ValueError("only bytes ranges supported")
        spec = range_header[len(prefix):].strip()
        if "-" not in spec:
            raise ValueError("invalid bytes range")

        left, right = spec.split("-", 1)
        left = left.strip()
        right = right.strip()

        if left == "":
            if right == "":
                raise ValueError("invalid suffix range")
            try:
                suffix_len = int(right, 10)
            except ValueError as e:
                raise ValueError("invalid suffix length") from e
            if suffix_len <= 0:
                raise ValueError("invalid suffix length")
            if size == 0:
                raise ValueError("unsatisfiable")
            if suffix_len >= size:
                return 0, size - 1
            return size - suffix_len, size - 1

        try:
            start = int(left, 10)
        except ValueError as e:
            raise ValueError("invalid range start") from e
        if start < 0:
            raise ValueError("invalid range start")
        if start >= size:
            raise ValueError("unsatisfiable")

        if right == "":
            return start, size - 1

        try:
            end = int(right, 10)
        except ValueError as e:
            raise ValueError("invalid range end") from e
        if end < start:
            raise ValueError("unsatisfiable")
        if end >= size:
            end = size - 1
        return start, end

    def _parse_route(self) -> Tuple[Optional[str], Optional[str]]:
        path = self.path.split("?", 1)[0]
        parts = [p for p in path.split("/") if p]
        if len(parts) < 2 or parts[0] != "images":
            return None, None
        image_id = parts[1]
        tail = parts[2] if len(parts) >= 3 else None
        if len(parts) > 3:
            return None, None
        return image_id, tail

    def _parse_content_range(self, header: str) -> Tuple[int, int]:
        """
        Parse Content-Range header "bytes start-end/*" or "bytes start-end/size".
        Returns (start, end_inclusive).
        """
        if not header:
            raise ValueError("empty Content-Range")
        m = self._CONTENT_RANGE_RE.match(header.strip())
        if not m:
            raise ValueError("invalid Content-Range")
        start_s, end_s = m.groups()
        start = int(start_s, 10)
        end = int(end_s, 10)
        if start < 0 or end < start:
            raise ValueError("invalid Content-Range range")
        return start, end

    def _parse_query(self) -> Dict[str, List[str]]:
        if "?" not in self.path:
            return {}
        query = self.path.split("?", 1)[1]
        return parse_qs(query, keep_blank_values=True)

    def _image_cfg(self, image_id: str) -> Optional[Dict[str, Any]]:
        return self._registry.get(image_id)

    # ------------------------------------------------------------------
    # HTTP verb dispatchers
    # ------------------------------------------------------------------

    def do_OPTIONS(self) -> None:
        image_id, tail = self._parse_route()
        if image_id is None or tail is not None:
            self._send_error_json(HTTPStatus.NOT_FOUND, "not found")
            return
        cfg = self._image_cfg(image_id)
        if cfg is None:
            self._send_error_json(HTTPStatus.NOT_FOUND, "unknown image_id")
            return

        with self._registry.request_lifecycle(image_id):
            backend = create_backend(cfg)
            try:
                max_writers = MAX_PARALLEL_WRITES
                if not backend.supports_range_write:
                    max_writers = 1

                if not backend.supports_extents:
                    allowed_methods = "GET, PUT, POST, OPTIONS"
                    features = ["flush"]
                    response = {
                        "unix_socket": None,
                        "features": features,
                        "max_readers": MAX_PARALLEL_READS,
                        "max_writers": max_writers,
                    }
                    self._send_json(HTTPStatus.OK, response, allowed_methods=allowed_methods)
                    return

                read_only = True
                can_flush = False
                can_zero = False
                try:
                    caps = backend.get_capabilities()
                    read_only = caps["read_only"]
                    can_flush = caps["can_flush"]
                    can_zero = caps["can_zero"]
                except Exception as e:
                    logging.warning("OPTIONS: could not query backend capabilities: %r", e)
                    read_only = bool(cfg.get("read_only"))
                    if not read_only:
                        can_flush = True
                        can_zero = True

                if read_only:
                    allowed_methods = "GET, OPTIONS"
                    features = ["extents"]
                    max_writers = 0
                else:
                    allowed_methods = "GET, PUT, PATCH, OPTIONS"
                    features = ["extents"]
                    if can_zero:
                        features.append("zero")
                    if can_flush:
                        features.append("flush")

                response = {
                    "unix_socket": None,
                    "features": features,
                    "max_readers": MAX_PARALLEL_READS,
                    "max_writers": max_writers,
                }
                self._send_json(HTTPStatus.OK, response, allowed_methods=allowed_methods)
            finally:
                backend.close()

    def do_GET(self) -> None:
        image_id, tail = self._parse_route()
        if image_id is None:
            self._send_error_json(HTTPStatus.NOT_FOUND, "not found")
            return

        cfg = self._image_cfg(image_id)
        if cfg is None:
            self._send_error_json(HTTPStatus.NOT_FOUND, "unknown image_id")
            return

        if tail == "extents":
            with self._registry.request_lifecycle(image_id):
                query = self._parse_query()
                context = (query.get("context") or [None])[0]
                self._handle_get_extents(image_id, cfg, context=context)
            return
        if tail is not None:
            self._send_error_json(HTTPStatus.NOT_FOUND, "not found")
            return

        range_header = self.headers.get("Range")
        with self._registry.request_lifecycle(image_id):
            self._handle_get_image(image_id, cfg, range_header)

    def do_PUT(self) -> None:
        image_id, tail = self._parse_route()
        if image_id is None or tail is not None:
            self._send_error_json(HTTPStatus.NOT_FOUND, "not found")
            return

        cfg = self._image_cfg(image_id)
        if cfg is None:
            self._send_error_json(HTTPStatus.NOT_FOUND, "unknown image_id")
            return

        with self._registry.request_lifecycle(image_id):
            if self.headers.get("Range") is not None:
                self._send_error_json(
                    HTTPStatus.BAD_REQUEST,
                    "Range header not supported for PUT; use Content-Range or PATCH",
                )
                return

            content_length_hdr = self.headers.get("Content-Length")
            if content_length_hdr is None:
                self._send_error_json(HTTPStatus.BAD_REQUEST, "Content-Length required")
                return
            try:
                content_length = int(content_length_hdr)
            except ValueError:
                self._send_error_json(HTTPStatus.BAD_REQUEST, "Invalid Content-Length")
                return
            if content_length < 0:
                self._send_error_json(HTTPStatus.BAD_REQUEST, "Invalid Content-Length")
                return

            query = self._parse_query()
            flush_param = (query.get("flush") or ["n"])[0].lower()
            flush = flush_param in ("y", "yes", "true", "1")

            content_range_hdr = self.headers.get("Content-Range")
            if content_range_hdr is not None:
                backend = create_backend(cfg)
                try:
                    if not backend.supports_range_write:
                        self._send_error_json(
                            HTTPStatus.BAD_REQUEST,
                            "Content-Range PUT not supported for file backend; use full PUT",
                        )
                        return
                    self._handle_put_range_with_backend(
                        image_id,
                        backend,
                        content_range_hdr,
                        content_length,
                        flush,
                    )
                finally:
                    backend.close()
                return

            self._handle_put_image(image_id, cfg, content_length, flush)

    def do_POST(self) -> None:
        image_id, tail = self._parse_route()
        if image_id is None:
            self._send_error_json(HTTPStatus.NOT_FOUND, "not found")
            return

        cfg = self._image_cfg(image_id)
        if cfg is None:
            self._send_error_json(HTTPStatus.NOT_FOUND, "unknown image_id")
            return

        if tail == "flush":
            with self._registry.request_lifecycle(image_id):
                self._handle_post_flush(image_id, cfg)
            return
        self._send_error_json(HTTPStatus.NOT_FOUND, "not found")

    def do_PATCH(self) -> None:
        image_id, tail = self._parse_route()
        if image_id is None or tail is not None:
            self._send_error_json(HTTPStatus.NOT_FOUND, "not found")
            return

        cfg = self._image_cfg(image_id)
        if cfg is None:
            self._send_error_json(HTTPStatus.NOT_FOUND, "unknown image_id")
            return

        with self._registry.request_lifecycle(image_id):
            backend = create_backend(cfg)
            try:
                if not backend.supports_range_write:
                    self._send_error_json(
                        HTTPStatus.BAD_REQUEST,
                        "range writes and PATCH not supported for file backend; use PUT for full upload",
                    )
                    return
                content_type = self.headers.get("Content-Type", "").split(";")[0].strip().lower()
                range_header = self.headers.get("Range")

                if range_header is not None and content_type != "application/json":
                    content_length_hdr = self.headers.get("Content-Length")
                    if content_length_hdr is None:
                        self._send_error_json(HTTPStatus.BAD_REQUEST, "Content-Length required")
                        return
                    try:
                        content_length = int(content_length_hdr)
                    except ValueError:
                        self._send_error_json(HTTPStatus.BAD_REQUEST, "Invalid Content-Length")
                        return
                    if content_length <= 0:
                        self._send_error_json(HTTPStatus.BAD_REQUEST, "Content-Length must be positive")
                        return
                    self._handle_patch_range_with_backend(
                        image_id,
                        backend,
                        range_header,
                        content_length,
                    )
                    return

                if content_type != "application/json":
                    self._send_error_json(
                        HTTPStatus.UNSUPPORTED_MEDIA_TYPE,
                        "PATCH requires Content-Type: application/json (for zero/flush) or Range with binary body",
                    )
                    return

                content_length_hdr = self.headers.get("Content-Length")
                if content_length_hdr is None:
                    self._send_error_json(HTTPStatus.BAD_REQUEST, "Content-Length required")
                    return
                try:
                    content_length = int(content_length_hdr)
                except ValueError:
                    self._send_error_json(HTTPStatus.BAD_REQUEST, "Invalid Content-Length")
                    return
                if content_length <= 0 or content_length > MAX_PATCH_JSON_SIZE:
                    self._send_error_json(HTTPStatus.BAD_REQUEST, "Invalid Content-Length")
                    return

                body = self.rfile.read(content_length)
                if len(body) != content_length:
                    self._send_error_json(HTTPStatus.BAD_REQUEST, "request body truncated")
                    return

                try:
                    payload = json.loads(body.decode("utf-8"))
                except (json.JSONDecodeError, UnicodeDecodeError) as e:
                    self._send_error_json(HTTPStatus.BAD_REQUEST, f"invalid JSON: {e}")
                    return

                if not isinstance(payload, dict):
                    self._send_error_json(HTTPStatus.BAD_REQUEST, "body must be a JSON object")
                    return

                op = payload.get("op")
                if op == "flush":
                    self._handle_post_flush_with_backend(image_id, backend)
                    return
                if op != "zero":
                    self._send_error_json(
                        HTTPStatus.BAD_REQUEST,
                        "unsupported op; only \"zero\" and \"flush\" are supported",
                    )
                    return

                try:
                    size = int(payload.get("size"))
                except (TypeError, ValueError):
                    self._send_error_json(HTTPStatus.BAD_REQUEST, "missing or invalid \"size\"")
                    return
                if size <= 0:
                    self._send_error_json(HTTPStatus.BAD_REQUEST, "\"size\" must be positive")
                    return

                offset = payload.get("offset")
                if offset is None:
                    offset = 0
                else:
                    try:
                        offset = int(offset)
                    except (TypeError, ValueError):
                        self._send_error_json(HTTPStatus.BAD_REQUEST, "invalid \"offset\"")
                        return
                    if offset < 0:
                        self._send_error_json(HTTPStatus.BAD_REQUEST, "\"offset\" must be non-negative")
                        return

                flush = bool(payload.get("flush", False))
                self._handle_patch_zero_with_backend(
                    image_id,
                    backend,
                    offset=offset,
                    size=size,
                    flush=flush,
                )
            finally:
                backend.close()

    # ------------------------------------------------------------------
    # Operation handlers
    # ------------------------------------------------------------------

    def _handle_get_image(
        self, image_id: str, cfg: Dict[str, Any], range_header: Optional[str]
    ) -> None:
        start = now_s()
        bytes_sent = 0
        expected_bytes = 0
        try:
            logging.debug("GET start image_id=%s range=%s", image_id, range_header or "-")
            backend = create_backend(cfg)
            session = None
            try:
                session = backend.open_session()
                size = session.size()
            except OSError as e:
                logging.error("GET size error image_id=%s err=%r", image_id, e)
                self._send_error_json(HTTPStatus.INTERNAL_SERVER_ERROR, "failed to access image")
                if session is not None:
                    session.close()
                backend.close()
                return

            try:
                start_off = 0
                end_off_incl = size - 1 if size > 0 else -1
                status = HTTPStatus.OK
                content_length = size
                if range_header is not None:
                    try:
                        start_off, end_off_incl = self._parse_single_range(range_header, size)
                    except ValueError as e:
                        if "unsatisfiable" in str(e):
                            self._send_range_not_satisfiable(size)
                            return
                        self._send_error_json(HTTPStatus.BAD_REQUEST, "invalid Range header")
                        return
                    status = HTTPStatus.PARTIAL_CONTENT
                    content_length = (end_off_incl - start_off) + 1
                expected_bytes = content_length

                self.send_response(status)
                self._send_imageio_headers()
                self.send_header("Content-Type", "application/octet-stream")
                self.send_header("Content-Length", str(content_length))
                if status == HTTPStatus.PARTIAL_CONTENT:
                    self.send_header("Content-Range", f"bytes {start_off}-{end_off_incl}/{size}")
                self.end_headers()

                offset = start_off
                end_excl = end_off_incl + 1
                while offset < end_excl:
                    to_read = min(CHUNK_SIZE, end_excl - offset)
                    data = session.read(offset, to_read)
                    if not data:
                        logging.error(
                            "GET short read image_id=%s expected_bytes=%d sent_bytes=%d offset=%d",
                            image_id,
                            expected_bytes,
                            bytes_sent,
                            offset,
                        )
                        self.close_connection = True
                        break
                    try:
                        self.wfile.write(data)
                    except BrokenPipeError:
                        logging.error(
                            "GET client disconnected image_id=%s at=%d expected_bytes=%d sent_bytes=%d",
                            image_id,
                            offset,
                            expected_bytes,
                            bytes_sent,
                        )
                        self.close_connection = True
                        break
                    offset += len(data)
                    bytes_sent += len(data)
            finally:
                session.close()
                backend.close()
        except Exception as e:
            logging.error("GET error image_id=%s err=%r", image_id, e)
            try:
                if not self.wfile.closed:
                    self.close_connection = True
            except Exception:
                pass
        finally:
            if expected_bytes > 0 and bytes_sent < expected_bytes:
                logging.error(
                    "GET incomplete image_id=%s expected_bytes=%d sent_bytes=%d",
                    image_id,
                    expected_bytes,
                    bytes_sent,
                )
            dur = now_s() - start
            logging.debug(
                "GET end image_id=%s bytes=%d duration_s=%.3f", image_id, bytes_sent, dur
            )

    def _handle_put_image(
        self, image_id: str, cfg: Dict[str, Any], content_length: int, flush: bool
    ) -> None:
        start = now_s()
        bytes_written = 0
        try:
            logging.debug("PUT start image_id=%s content_length=%d", image_id, content_length)
            backend = create_backend(cfg)
            try:
                bytes_written = backend.write_full(self.rfile, content_length, flush)
                self._send_json(
                    HTTPStatus.OK,
                    {"ok": True, "bytes_written": bytes_written, "flushed": flush},
                )
            except IOError as e:
                self._send_error_json(HTTPStatus.BAD_REQUEST, str(e))
            finally:
                backend.close()
        except Exception as e:
            logging.error("PUT error image_id=%s err=%r", image_id, e)
            self._send_error_json(HTTPStatus.INTERNAL_SERVER_ERROR, "backend error")
        finally:
            dur = now_s() - start
            logging.debug(
                "PUT end image_id=%s bytes=%d duration_s=%.3f", image_id, bytes_written, dur
            )

    def _handle_put_range(
        self,
        image_id: str,
        cfg: Dict[str, Any],
        content_range: str,
        content_length: int,
        flush: bool,
    ) -> None:
        backend = create_backend(cfg)
        try:
            self._handle_put_range_with_backend(
                image_id,
                backend,
                content_range,
                content_length,
                flush,
            )
        finally:
            backend.close()

    def _handle_put_range_with_backend(
        self,
        image_id: str,
        backend: NbdBackend,
        content_range: str,
        content_length: int,
        flush: bool,
    ) -> None:
        start = now_s()
        bytes_written = 0
        try:
            logging.debug(
                "PUT range start image_id=%s Content-Range=%s content_length=%d flush=%s",
                image_id, content_range, content_length, flush,
            )
            try:
                start_off, _end_inclusive = self._parse_content_range(content_range)
            except ValueError as e:
                self._send_error_json(
                    HTTPStatus.BAD_REQUEST, f"invalid Content-Range header: {e}"
                )
                return

            try:
                bytes_written = backend.write_range(self.rfile, start_off, content_length)
                if flush:
                    backend.flush()
                self._send_json(
                    HTTPStatus.OK,
                    {"ok": True, "bytes_written": bytes_written, "flushed": flush},
                )
            except ValueError:
                image_size = backend.size()
                self._send_range_not_satisfiable(image_size)
            except IOError as e:
                self._send_error_json(HTTPStatus.BAD_REQUEST, str(e))
        except Exception as e:
            logging.error("PUT range error image_id=%s err=%r", image_id, e)
            self._send_error_json(HTTPStatus.INTERNAL_SERVER_ERROR, "backend error")
        finally:
            dur = now_s() - start
            logging.debug(
                "PUT range end image_id=%s bytes=%d duration_s=%.3f flush=%s",
                image_id, bytes_written, dur, flush,
            )

    def _handle_get_extents(
        self, image_id: str, cfg: Dict[str, Any], context: Optional[str] = None
    ) -> None:
        backend = create_backend(cfg)
        try:
            self._handle_get_extents_with_backend(image_id, backend, context=context)
        finally:
            backend.close()

    def _handle_get_extents_with_backend(
        self, image_id: str, backend: NbdBackend, context: Optional[str] = None
    ) -> None:
        start = now_s()
        try:
            logging.info("EXTENTS start image_id=%s context=%s", image_id, context)
            if not backend.supports_extents:
                self._send_error_json(
                    HTTPStatus.BAD_REQUEST, "extents not supported for file backend"
                )
                return
            if context == "dirty":
                export_bitmap = backend.export_bitmap
                if not export_bitmap:
                    allocation = backend.get_allocation_extents()
                    extents: List[Dict[str, Any]] = [
                        {"start": e["start"], "length": e["length"], "dirty": True, "zero": e["zero"]}
                        for e in allocation
                    ]
                else:
                    dirty_bitmap_ctx = f"qemu:dirty-bitmap:{export_bitmap}"
                    extents = backend.get_dirty_extents(dirty_bitmap_ctx)
                    if is_fallback_dirty_response(extents):
                        logging.warning(
                            "EXTENTS image_id=%s: no usable dirty bitmap data for "
                            "context %r; reporting all allocated extents as dirty",
                            image_id, dirty_bitmap_ctx,
                        )
                        allocation = backend.get_allocation_extents()
                        extents = [
                            {
                                "start": e["start"],
                                "length": e["length"],
                                "dirty": True,
                                "zero": e["zero"],
                            }
                            for e in allocation
                        ]
            else:
                extents = backend.get_allocation_extents()
            self._send_json(HTTPStatus.OK, extents)
        except Exception as e:
            logging.error("EXTENTS error image_id=%s err=%r", image_id, e)
            self._send_error_json(HTTPStatus.INTERNAL_SERVER_ERROR, "backend error")
        finally:
            dur = now_s() - start
            logging.info("EXTENTS end image_id=%s duration_s=%.3f", image_id, dur)

    def _handle_post_flush(self, image_id: str, cfg: Dict[str, Any]) -> None:
        backend = create_backend(cfg)
        try:
            self._handle_post_flush_with_backend(image_id, backend)
        finally:
            backend.close()

    def _handle_post_flush_with_backend(self, image_id: str, backend: NbdBackend) -> None:
        start = now_s()
        try:
            logging.info("FLUSH start image_id=%s", image_id)
            backend.flush()
            self._send_json(HTTPStatus.OK, {"ok": True})
        except Exception as e:
            logging.error("FLUSH error image_id=%s err=%r", image_id, e)
            self._send_error_json(HTTPStatus.INTERNAL_SERVER_ERROR, "backend error")
        finally:
            dur = now_s() - start
            logging.info("FLUSH end image_id=%s duration_s=%.3f", image_id, dur)

    def _handle_patch_zero(
        self,
        image_id: str,
        cfg: Dict[str, Any],
        offset: int,
        size: int,
        flush: bool,
    ) -> None:
        backend = create_backend(cfg)
        try:
            self._handle_patch_zero_with_backend(image_id, backend, offset, size, flush)
        finally:
            backend.close()

    def _handle_patch_zero_with_backend(
        self,
        image_id: str,
        backend: NbdBackend,
        offset: int,
        size: int,
        flush: bool,
    ) -> None:
        start = now_s()
        try:
            logging.debug(
                "PATCH zero start image_id=%s offset=%d size=%d flush=%s",
                image_id, offset, size, flush,
            )
            backend.zero(offset, size)
            if flush:
                backend.flush()
            self._send_json(HTTPStatus.OK, {"ok": True})
        except ValueError as e:
            self._send_error_json(HTTPStatus.BAD_REQUEST, str(e))
        except Exception as e:
            logging.error("PATCH zero error image_id=%s err=%r", image_id, e)
            self._send_error_json(HTTPStatus.INTERNAL_SERVER_ERROR, "backend error")
        finally:
            dur = now_s() - start
            logging.debug("PATCH zero end image_id=%s duration_s=%.3f", image_id, dur)

    def _handle_patch_range(
        self,
        image_id: str,
        cfg: Dict[str, Any],
        range_header: str,
        content_length: int,
    ) -> None:
        backend = create_backend(cfg)
        try:
            self._handle_patch_range_with_backend(
                image_id,
                backend,
                range_header,
                content_length,
            )
        finally:
            backend.close()

    def _handle_patch_range_with_backend(
        self,
        image_id: str,
        backend: NbdBackend,
        range_header: str,
        content_length: int,
    ) -> None:
        start = now_s()
        bytes_written = 0
        try:
            logging.debug(
                "PATCH range start image_id=%s range=%s content_length=%d",
                image_id, range_header, content_length,
            )
            try:
                image_size = backend.size()
                try:
                    start_off, end_inclusive = self._parse_single_range(
                        range_header, image_size
                    )
                except ValueError as e:
                    if "unsatisfiable" in str(e).lower():
                        self._send_range_not_satisfiable(image_size)
                    else:
                        self._send_error_json(
                            HTTPStatus.BAD_REQUEST, f"invalid Range header: {e}"
                        )
                    return
                expected_len = end_inclusive - start_off + 1
                if content_length != expected_len:
                    self._send_error_json(
                        HTTPStatus.BAD_REQUEST,
                        f"Content-Length ({content_length}) must equal range length ({expected_len})",
                    )
                    return
                nbd_backend: NbdBackend = backend  # type: ignore[assignment]
                bytes_written = nbd_backend.write_range(self.rfile, start_off, content_length)
                self._send_json(HTTPStatus.OK, {"ok": True, "bytes_written": bytes_written})
            except ValueError:
                image_size = backend.size()
                self._send_range_not_satisfiable(image_size)
            except IOError as e:
                self._send_error_json(HTTPStatus.BAD_REQUEST, str(e))
        except Exception as e:
            logging.error("PATCH range error image_id=%s err=%r", image_id, e)
            self._send_error_json(HTTPStatus.INTERNAL_SERVER_ERROR, "backend error")
        finally:
            dur = now_s() - start
            logging.debug(
                "PATCH range end image_id=%s bytes=%d duration_s=%.3f",
                image_id, bytes_written, dur,
            )
