import { __esDecorate, __runInitializers } from "tslib";
import { MessagePriority, encodeNodeID, parseNodeID } from "@zwave-js/core";
import { FunctionType, Message, MessageOrigin, MessageType, expectedCallback, expectedResponse, messageTypes, priority, } from "@zwave-js/serial";
import { Bytes } from "@zwave-js/shared";
export var RemoveFailedNodeStartFlags;
(function (RemoveFailedNodeStartFlags) {
    RemoveFailedNodeStartFlags[RemoveFailedNodeStartFlags["OK"] = 0] = "OK";
    /** The removing process was aborted because the controller  is not the primary one */
    RemoveFailedNodeStartFlags[RemoveFailedNodeStartFlags["NotPrimaryController"] = 2] = "NotPrimaryController";
    /** The removing process was aborted because no call back function is used */
    RemoveFailedNodeStartFlags[RemoveFailedNodeStartFlags["NoCallbackFunction"] = 4] = "NoCallbackFunction";
    /** The removing process aborted because the node was node found */
    RemoveFailedNodeStartFlags[RemoveFailedNodeStartFlags["NodeNotFound"] = 8] = "NodeNotFound";
    /** The removing process is busy */
    RemoveFailedNodeStartFlags[RemoveFailedNodeStartFlags["RemoveProcessBusy"] = 16] = "RemoveProcessBusy";
    /** The removing process could not be started*/
    RemoveFailedNodeStartFlags[RemoveFailedNodeStartFlags["RemoveFailed"] = 32] = "RemoveFailed";
})(RemoveFailedNodeStartFlags || (RemoveFailedNodeStartFlags = {}));
export var RemoveFailedNodeStatus;
(function (RemoveFailedNodeStatus) {
    /* ZW_RemoveFailedNode and ZW_ReplaceFailedNode callback status definitions */
    /** The node is working properly (removed from the failed nodes list ) */
    RemoveFailedNodeStatus[RemoveFailedNodeStatus["NodeOK"] = 0] = "NodeOK";
    /* ZW_RemoveFailedNode callback status definitions */
    /** The failed node was removed from the failed nodes list */
    RemoveFailedNodeStatus[RemoveFailedNodeStatus["NodeRemoved"] = 1] = "NodeRemoved";
    /** The failed node was not removed from the failing nodes list */
    RemoveFailedNodeStatus[RemoveFailedNodeStatus["NodeNotRemoved"] = 2] = "NodeNotRemoved";
})(RemoveFailedNodeStatus || (RemoveFailedNodeStatus = {}));
let RemoveFailedNodeRequestBase = (() => {
    let _classDecorators = [messageTypes(MessageType.Request, FunctionType.RemoveFailedNode), priority(MessagePriority.Controller)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = Message;
    var RemoveFailedNodeRequestBase = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            RemoveFailedNodeRequestBase = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        static from(raw, ctx) {
            if (ctx.origin === MessageOrigin.Host) {
                return RemoveFailedNodeRequest.from(raw, ctx);
            }
            else {
                return RemoveFailedNodeRequestStatusReport.from(raw, ctx);
            }
        }
    };
    return RemoveFailedNodeRequestBase = _classThis;
})();
export { RemoveFailedNodeRequestBase };
let RemoveFailedNodeRequest = (() => {
    let _classDecorators = [expectedResponse(FunctionType.RemoveFailedNode), expectedCallback(FunctionType.RemoveFailedNode)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = RemoveFailedNodeRequestBase;
    var RemoveFailedNodeRequest = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            RemoveFailedNodeRequest = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.failedNodeId = options.failedNodeId;
        }
        static from(raw, ctx) {
            const { nodeId: failedNodeId, bytesRead } = parseNodeID(raw.payload, ctx.nodeIdType);
            const callbackId = raw.payload[bytesRead];
            return new this({
                failedNodeId,
                callbackId,
            });
        }
        // This must not be called nodeId or rejectAllTransactions may reject the request
        /** The node that should be removed */
        failedNodeId;
        serialize(ctx) {
            this.assertCallbackId();
            const nodeId = encodeNodeID(this.failedNodeId, ctx.nodeIdType);
            this.payload = Bytes.concat([nodeId, [this.callbackId]]);
            return super.serialize(ctx);
        }
    };
    return RemoveFailedNodeRequest = _classThis;
})();
export { RemoveFailedNodeRequest };
export class RemoveFailedNodeRequestStatusReport extends RemoveFailedNodeRequestBase {
    constructor(options) {
        super(options);
        // TODO: Check implementation:
        this.callbackId = options.callbackId;
        this.removeStatus = options.removeStatus;
    }
    static from(raw, _ctx) {
        const callbackId = raw.payload[0];
        const removeStatus = raw.payload[1];
        return new this({
            callbackId,
            removeStatus,
        });
    }
    removeStatus;
    isOK() {
        return this.removeStatus === RemoveFailedNodeStatus.NodeRemoved;
    }
}
let RemoveFailedNodeResponse = (() => {
    let _classDecorators = [messageTypes(MessageType.Response, FunctionType.RemoveFailedNode)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = Message;
    var RemoveFailedNodeResponse = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            RemoveFailedNodeResponse = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.removeStatus = options.removeStatus;
        }
        static from(raw, _ctx) {
            const removeStatus = raw.payload[0];
            return new this({
                removeStatus,
            });
        }
        removeStatus;
        isOK() {
            return this.removeStatus === RemoveFailedNodeStartFlags.OK;
        }
    };
    return RemoveFailedNodeResponse = _classThis;
})();
export { RemoveFailedNodeResponse };
//# sourceMappingURL=RemoveFailedNodeMessages.js.map