from dataclasses import dataclass
from ayradb.rest.http.response import Response
from ayradb.core.manage_record.unescape import *

FIELD_SEPARATOR = b'\x3b'
RECORD_SEPARATOR = b'\n'


class QueryError:
    TABLE_NOT_FOUND = 1
    FIELD_NOT_FOUND = 2
    GENERIC_ERROR = 100


ERROR_DICT = {
    'ERROR: TFA_MTKO_016: trans_h__manage_transaction_kick_off__sqlq:ERROR: [00400]:(00006): MTKOSQLQ_001.001: error in trans_h__manage_transaction_kick_off__sqlq__primary: ERROR: [00400]:(00006): MTKOSQLQPRI_013: could not decompose the sql command: ERROR: [00400]:(00006): DECOMPSQLCOM_060: error in sql_h__decompose_command__select: ERROR: [00400]:(00006): DECOMPSQLCOMSELECT_020.001.002: the table does not exist' : QueryError.TABLE_NOT_FOUND
}


@dataclass
class QueryResponse:

    success: bool
    content: list
    error_code: int
    _error_msg: str

    def __init__(self, success, error_code, content=None, _error_msg=""):
        self.success = success
        self.error_code = error_code
        self.content = content
        self._error_msg = _error_msg

    @staticmethod
    def from_http_response(res: Response):
        if res.status_code == 200:
            body: bytes = res.body
            records = body.split(RECORD_SEPARATOR)
            content = []
            if records[records.__len__()-1] == b'':
                # Remove empty b'' generated by the last record terminator
                records.pop(records.__len__()-1)
            for record in records:
                columns = record.split(FIELD_SEPARATOR)
                record = {}
                for cursor in range(0, columns.__len__(), 2):
                    # For every pair key-value in the record
                    # splitted body is organized as [key, value, key, value, ...]
                    field_key = columns[cursor]
                    field_value = unescape(columns[cursor + 1])
                    record[field_key.decode('utf-8')] = field_value
                content.append(record)
            return QueryResponse(True, 0, content=content)
        else:
            return QueryResponse(False, QueryError.GENERIC_ERROR, content=[])


