import { __esDecorate, __runInitializers } from "tslib";
import { MessagePriority, ZWaveError, ZWaveErrorCodes, } from "@zwave-js/core";
import { FunctionType, Message, MessageOrigin, MessageType, expectedResponse, messageTypes, priority, } from "@zwave-js/serial";
import { Bytes, buffer2hex, getEnumMemberName, } from "@zwave-js/shared";
const LEARN_MODE_EMPTY_NODE_ID = 0xef; // who knows why...
export var LearnModeIntent;
(function (LearnModeIntent) {
    LearnModeIntent[LearnModeIntent["LegacyStop"] = 0] = "LegacyStop";
    LearnModeIntent[LearnModeIntent["LegacyInclusionExclusion"] = 1] = "LegacyInclusionExclusion";
    LearnModeIntent[LearnModeIntent["LegacyNetworkWideInclusion"] = 2] = "LegacyNetworkWideInclusion";
    LearnModeIntent[LearnModeIntent["LegacyNetworkWideExclusion"] = 3] = "LegacyNetworkWideExclusion";
    LearnModeIntent[LearnModeIntent["Stop"] = 128] = "Stop";
    // The Z-Wave API Module SHOULD try a direct range inclusion followed by 4 NWI attempts
    LearnModeIntent[LearnModeIntent["Inclusion"] = 129] = "Inclusion";
    LearnModeIntent[LearnModeIntent["DirectExclusion"] = 130] = "DirectExclusion";
    LearnModeIntent[LearnModeIntent["NetworkWideExclusion"] = 131] = "NetworkWideExclusion";
    LearnModeIntent[LearnModeIntent["SmartStart"] = 132] = "SmartStart";
})(LearnModeIntent || (LearnModeIntent = {}));
export var LearnModeStatus;
(function (LearnModeStatus) {
    LearnModeStatus[LearnModeStatus["Started"] = 1] = "Started";
    LearnModeStatus[LearnModeStatus["ProtocolDone"] = 5] = "ProtocolDone";
    LearnModeStatus[LearnModeStatus["Completed"] = 6] = "Completed";
    LearnModeStatus[LearnModeStatus["Failed"] = 7] = "Failed";
})(LearnModeStatus || (LearnModeStatus = {}));
let SetLearnModeRequestBase = (() => {
    let _classDecorators = [messageTypes(MessageType.Request, FunctionType.SetLearnMode), priority(MessagePriority.Controller)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = Message;
    var SetLearnModeRequestBase = 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);
            SetLearnModeRequestBase = _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 SetLearnModeRequest.from(raw, ctx);
            }
            else {
                return SetLearnModeCallback.from(raw, ctx);
            }
        }
    };
    return SetLearnModeRequestBase = _classThis;
})();
export { SetLearnModeRequestBase };
let SetLearnModeRequest = (() => {
    let _classDecorators = [expectedResponse(FunctionType.SetLearnMode)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = SetLearnModeRequestBase;
    var SetLearnModeRequest = 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);
            SetLearnModeRequest = _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.intent = options.intent;
        }
        static from(_raw, _ctx) {
            throw new ZWaveError(`${this.name}: deserialization not implemented`, ZWaveErrorCodes.Deserialization_NotImplemented);
            // return new SetLearnModeRequest({});
        }
        intent;
        serialize(ctx) {
            this.assertCallbackId();
            this.payload = Bytes.from([
                this.intent,
                this.callbackId,
            ]);
            return super.serialize(ctx);
        }
        toLogEntry() {
            return {
                ...super.toLogEntry(),
                message: {
                    "callback id": this.callbackId ?? "(not set)",
                    intent: getEnumMemberName(LearnModeIntent, this.intent),
                },
            };
        }
    };
    return SetLearnModeRequest = _classThis;
})();
export { SetLearnModeRequest };
let SetLearnModeResponse = (() => {
    let _classDecorators = [messageTypes(MessageType.Response, FunctionType.SetLearnMode)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = Message;
    var SetLearnModeResponse = 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);
            SetLearnModeResponse = _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);
            // TODO: Check implementation:
            this.success = options.success;
        }
        static from(raw, _ctx) {
            const success = raw.payload[0] !== 0;
            return new this({
                success,
            });
        }
        success;
        isOK() {
            return this.success;
        }
        toLogEntry() {
            return {
                ...super.toLogEntry(),
                message: { success: this.success },
            };
        }
    };
    return SetLearnModeResponse = _classThis;
})();
export { SetLearnModeResponse };
export class SetLearnModeCallback extends SetLearnModeRequestBase {
    constructor(options) {
        super(options);
        // TODO: Check implementation:
        this.callbackId = options.callbackId;
        this.status = options.status;
        this.assignedNodeId = options.assignedNodeId;
        this.statusMessage = options.statusMessage;
    }
    static from(raw, _ctx) {
        const callbackId = raw.payload[0];
        const status = raw.payload[1];
        const assignedNodeId = raw.payload[2];
        let statusMessage;
        if (raw.payload.length > 3) {
            const msgLength = raw.payload[3];
            statusMessage = raw.payload.subarray(4, 4 + msgLength);
        }
        return new this({
            callbackId,
            status,
            assignedNodeId,
            statusMessage,
        });
    }
    status;
    assignedNodeId;
    statusMessage;
    isOK() {
        return this.status !== LearnModeStatus.Failed;
    }
    toLogEntry() {
        const message = {
            "callback id": this.callbackId ?? "(not set)",
            status: getEnumMemberName(LearnModeStatus, this.status),
        };
        if (this.status !== LearnModeStatus.Started
            || this.assignedNodeId !== LEARN_MODE_EMPTY_NODE_ID) {
            message["assigned node id"] = this.assignedNodeId;
        }
        if (this.statusMessage?.length) {
            message["status message"] = buffer2hex(this.statusMessage);
        }
        return {
            ...super.toLogEntry(),
            message,
        };
    }
}
//# sourceMappingURL=SetLearnModeMessages.js.map