# Path: couchbaseConstants.py
# AUDIT_PKT_FMT = ">I"
# 
# INCRDECR_RES_FMT = ">Q"
# 
# MIN_RECV_PACKET = struct.calcsize(REQ_PKT_FMT)
# 
# REQ_MAGIC_BYTE = 0x80
# 
# REQ_PKT_FMT = ">BBHBBHIIQ"
# 
# RES_MAGIC_BYTE = 0x81
# 
# RES_PKT_FMT = ">BBHBBHIIQ"
# 
# SET_PKT_FMT = ">II"


import array
import random
import socket
import ssl
import struct
import couchbaseConstants
from typing import Iterable, List, Optional, Tuple, Union
from couchbaseConstants import (AUDIT_PKT_FMT, INCRDECR_RES_FMT, MIN_RECV_PACKET, REQ_MAGIC_BYTE, REQ_PKT_FMT,
                                RES_MAGIC_BYTE, RES_PKT_FMT, SET_PKT_FMT)
    from cb_version import VERSION  # pylint: disable=import-error
        if errcode != 0:
            raise MemcachedError(errcode, str(rv))
        return cmd, opaque, cas, keylen, extralen, rv

    def _handle_single_response(self, myopaque: Union[int, None]) -> Tuple[int, int, bytes]:
        cmd, opaque, cas, keylen, extralen, data = self._handle_keyed_response(myopaque)
        return opaque, cas, data

    def _do_cmd(self, cmd: int, key: bytes, val: bytes, extra_header: bytes = b'',
                cas: int = 0) -> Tuple[int, int, bytes]:
        """Send a command and await its response."""
        opaque = self.r.randint(0, 2**32)
        self._send_cmd(cmd, key, val, opaque, extra_header, cas)
        return self._handle_single_response(opaque)

    def _mutate(self, cmd: int, key: bytes, exp: int, flags: int, cas: int, val: bytes) -> Tuple[int, int, bytes]:
        return self._do_cmd(cmd, key, val, struct.pack(SET_PKT_FMT, flags, exp), cas)

    def _cat(self, cmd: int, key: bytes, cas: int, val: bytes) -> Tuple[int, int, bytes]:
        return self._do_cmd(cmd, key, val, b'', cas)

    def append(self, key: bytes, value: bytes, cas: int = 0) -> Tuple[int, int, bytes]:
        return self._cat(couchbaseConstants.CMD_APPEND, key, cas, value)

    def prepend(self, key: bytes, value: bytes, cas: int = 0) -> Tuple[int, int, bytes]:
        return self._cat(couchbaseConstants.CMD_PREPEND, key, cas, value)

    def __incrdecr(self, cmd, key, amt, init, exp):
        something, cas, val = self._do_cmd(cmd, key, b'',
                                           struct.pack(couchbaseConstants.INCRDECR_PKT_FMT, amt, init, exp))

# Path: couchbaseConstants.py
# AUDIT_PKT_FMT = ">I"
# 
# INCRDECR_RES_FMT = ">Q"
# 
# MIN_RECV_PACKET = struct.calcsize(REQ_PKT_FMT)
# 
# REQ_MAGIC_BYTE = 0x80
# 
# REQ_PKT_FMT = ">BBHBBHIIQ"
# 
# RES_MAGIC_BYTE = 0x81
# 
# RES_PKT_FMT = ">BBHBBHIIQ"
# 
# SET_PKT_FMT = ">II"


# Path: cb_bin_client.py
import array
import random
import socket
import ssl
import struct
import couchbaseConstants
from typing import Iterable, List, Optional, Tuple, Union
from couchbaseConstants import (AUDIT_PKT_FMT, INCRDECR_RES_FMT, MIN_RECV_PACKET, REQ_MAGIC_BYTE, REQ_PKT_FMT,
                                RES_MAGIC_BYTE, RES_PKT_FMT, SET_PKT_FMT)
    from cb_version import VERSION  # pylint: disable=import-error

        if errcode != 0:
            raise MemcachedError(errcode, str(rv))
        return cmd, opaque, cas, keylen, extralen, rv

    def _handle_single_response(self, myopaque: Union[int, None]) -> Tuple[int, int, bytes]:
        cmd, opaque, cas, keylen, extralen, data = self._handle_keyed_response(myopaque)
        return opaque, cas, data

    def _do_cmd(self, cmd: int, key: bytes, val: bytes, extra_header: bytes = b'',
                cas: int = 0) -> Tuple[int, int, bytes]:
        """Send a command and await its response."""
        opaque = self.r.randint(0, 2**32)
        self._send_cmd(cmd, key, val, opaque, extra_header, cas)
        return self._handle_single_response(opaque)

    def _mutate(self, cmd: int, key: bytes, exp: int, flags: int, cas: int, val: bytes) -> Tuple[int, int, bytes]:
        return self._do_cmd(cmd, key, val, struct.pack(SET_PKT_FMT, flags, exp), cas)

    def _cat(self, cmd: int, key: bytes, cas: int, val: bytes) -> Tuple[int, int, bytes]:
        return self._do_cmd(cmd, key, val, b'', cas)

    def append(self, key: bytes, value: bytes, cas: int = 0) -> Tuple[int, int, bytes]:
        return self._cat(couchbaseConstants.CMD_APPEND, key, cas, value)

    def prepend(self, key: bytes, value: bytes, cas: int = 0) -> Tuple[int, int, bytes]:
        return self._cat(couchbaseConstants.CMD_PREPEND, key, cas, value)

    def __incrdecr(self, cmd, key, amt, init, exp):
        something, cas, val = self._do_cmd(cmd, key, b'',
                                           struct.pack(couchbaseConstants.INCRDECR_PKT_FMT, amt, init, exp))

        return struct.unpack(INCRDECR_RES_FMT, val)[0], cas