"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ReasonCodes = void 0;
const shared_1 = require("../shared");
exports.ReasonCodes = {
    0: '',
    1: 'Unacceptable protocol version',
    2: 'Identifier rejected',
    3: 'Server unavailable',
    4: 'Bad username or password',
    5: 'Not authorized',
    16: 'No matching subscribers',
    17: 'No subscription existed',
    128: 'Unspecified error',
    129: 'Malformed Packet',
    130: 'Protocol Error',
    131: 'Implementation specific error',
    132: 'Unsupported Protocol Version',
    133: 'Client Identifier not valid',
    134: 'Bad User Name or Password',
    135: 'Not authorized',
    136: 'Server unavailable',
    137: 'Server busy',
    138: 'Banned',
    139: 'Server shutting down',
    140: 'Bad authentication method',
    141: 'Keep Alive timeout',
    142: 'Session taken over',
    143: 'Topic Filter invalid',
    144: 'Topic Name invalid',
    145: 'Packet identifier in use',
    146: 'Packet Identifier not found',
    147: 'Receive Maximum exceeded',
    148: 'Topic Alias invalid',
    149: 'Packet too large',
    150: 'Message rate too high',
    151: 'Quota exceeded',
    152: 'Administrative action',
    153: 'Payload format invalid',
    154: 'Retain not supported',
    155: 'QoS not supported',
    156: 'Use another server',
    157: 'Server moved',
    158: 'Shared Subscriptions not supported',
    159: 'Connection rate exceeded',
    160: 'Maximum connect time',
    161: 'Subscription Identifiers not supported',
    162: 'Wildcard Subscriptions not supported',
};
const handleAck = (client, packet) => {
    const { messageId } = packet;
    const type = packet.cmd;
    let response = null;
    const cb = client.outgoing[messageId] ? client.outgoing[messageId].cb : null;
    let err = null;
    if (!cb) {
        client.log('_handleAck :: Server sent an ack in error. Ignoring.');
        return;
    }
    client.log('_handleAck :: packet type', type);
    switch (type) {
        case 'pubcomp':
        case 'puback': {
            const pubackRC = packet.reasonCode;
            if (pubackRC && pubackRC > 0 && pubackRC !== 16) {
                err = new shared_1.ErrorWithReasonCode(`Publish error: ${exports.ReasonCodes[pubackRC]}`, pubackRC);
                client['_removeOutgoingAndStoreMessage'](messageId, () => {
                    cb(err, packet);
                });
            }
            else {
                client['_removeOutgoingAndStoreMessage'](messageId, cb);
            }
            break;
        }
        case 'pubrec': {
            response = {
                cmd: 'pubrel',
                qos: 2,
                messageId,
            };
            const pubrecRC = packet.reasonCode;
            if (pubrecRC && pubrecRC > 0 && pubrecRC !== 16) {
                err = new shared_1.ErrorWithReasonCode(`Publish error: ${exports.ReasonCodes[pubrecRC]}`, pubrecRC);
                client['_removeOutgoingAndStoreMessage'](messageId, () => {
                    cb(err, packet);
                });
            }
            else {
                client['_sendPacket'](response);
            }
            break;
        }
        case 'suback': {
            delete client.outgoing[messageId];
            client.messageIdProvider.deallocate(messageId);
            const granted = packet.granted;
            for (let grantedI = 0; grantedI < granted.length; grantedI++) {
                const subackRC = granted[grantedI];
                if ((subackRC & 0x80) !== 0) {
                    err = new Error(`Subscribe error: ${exports.ReasonCodes[subackRC]}`);
                    err.code = subackRC;
                    const topics = client.messageIdToTopic[messageId];
                    if (topics) {
                        topics.forEach((topic) => {
                            delete client['_resubscribeTopics'][topic];
                        });
                    }
                }
            }
            delete client.messageIdToTopic[messageId];
            client['_invokeStoreProcessingQueue']();
            cb(err, packet);
            break;
        }
        case 'unsuback': {
            delete client.outgoing[messageId];
            client.messageIdProvider.deallocate(messageId);
            client['_invokeStoreProcessingQueue']();
            cb(null, packet);
            break;
        }
        default:
            client.emit('error', new Error('unrecognized packet type'));
    }
    if (client.disconnecting && Object.keys(client.outgoing).length === 0) {
        client.emit('outgoingEmpty');
    }
};
exports.default = handleAck;
//# sourceMappingURL=ack.js.map