import { __esDecorate, __runInitializers } from "tslib";
import { MAX_NODES, MAX_REPEATERS, MessagePriority, TransmitStatus, ZWaveDataRate, ZWaveError, ZWaveErrorCodes, encodeNodeID, } from "@zwave-js/core";
import { FunctionType, Message, MessageOrigin, MessageType, expectedCallback, expectedResponse, messageTypes, priority, } from "@zwave-js/serial";
import { Bytes, getEnumMemberName } from "@zwave-js/shared";
let AssignPriorityReturnRouteRequestBase = (() => {
    let _classDecorators = [messageTypes(MessageType.Request, FunctionType.AssignPriorityReturnRoute), priority(MessagePriority.Normal)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = Message;
    var AssignPriorityReturnRouteRequestBase = 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);
            AssignPriorityReturnRouteRequestBase = _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 AssignPriorityReturnRouteRequest.from(raw, ctx);
            }
            else {
                return AssignPriorityReturnRouteRequestTransmitReport.from(raw, ctx);
            }
        }
    };
    return AssignPriorityReturnRouteRequestBase = _classThis;
})();
export { AssignPriorityReturnRouteRequestBase };
let AssignPriorityReturnRouteRequest = (() => {
    let _classDecorators = [expectedResponse(FunctionType.AssignPriorityReturnRoute), expectedCallback(FunctionType.AssignPriorityReturnRoute)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = AssignPriorityReturnRouteRequestBase;
    var AssignPriorityReturnRouteRequest = 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);
            AssignPriorityReturnRouteRequest = _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);
            if (options.nodeId === options.destinationNodeId) {
                throw new ZWaveError(`The source and destination node must not be identical`, ZWaveErrorCodes.Argument_Invalid);
            }
            if (options.repeaters.length > MAX_REPEATERS
                || options.repeaters.some((id) => id < 1 || id > MAX_NODES)) {
                throw new ZWaveError(`The repeaters array must contain at most ${MAX_REPEATERS} node IDs between 1 and ${MAX_NODES}`, ZWaveErrorCodes.Argument_Invalid);
            }
            this.nodeId = options.nodeId;
            this.destinationNodeId = options.destinationNodeId;
            this.repeaters = options.repeaters;
            this.routeSpeed = options.routeSpeed;
        }
        static from(_raw, _ctx) {
            throw new ZWaveError(`${this.name}: deserialization not implemented`, ZWaveErrorCodes.Deserialization_NotImplemented);
            // return new AssignPriorityReturnRouteRequest({});
        }
        nodeId;
        destinationNodeId;
        repeaters;
        routeSpeed;
        serialize(ctx) {
            this.assertCallbackId();
            const nodeId = encodeNodeID(this.nodeId, ctx.nodeIdType);
            const destinationNodeId = encodeNodeID(this.destinationNodeId, ctx.nodeIdType);
            this.payload = Bytes.concat([
                nodeId,
                destinationNodeId,
                [
                    this.repeaters[0] ?? 0,
                    this.repeaters[1] ?? 0,
                    this.repeaters[2] ?? 0,
                    this.repeaters[3] ?? 0,
                    this.routeSpeed,
                    this.callbackId,
                ],
            ]);
            return super.serialize(ctx);
        }
        toLogEntry() {
            return {
                ...super.toLogEntry(),
                message: {
                    "source node ID": this.nodeId,
                    "destination node ID": this.destinationNodeId,
                    repeaters: this.repeaters.length > 0
                        ? this.repeaters.join(" -> ")
                        : "none",
                    "route speed": getEnumMemberName(ZWaveDataRate, this.routeSpeed),
                    "callback id": this.callbackId ?? "(not set)",
                },
            };
        }
    };
    return AssignPriorityReturnRouteRequest = _classThis;
})();
export { AssignPriorityReturnRouteRequest };
let AssignPriorityReturnRouteResponse = (() => {
    let _classDecorators = [messageTypes(MessageType.Response, FunctionType.AssignPriorityReturnRoute)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = Message;
    var AssignPriorityReturnRouteResponse = 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);
            AssignPriorityReturnRouteResponse = _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.hasStarted = options.hasStarted;
        }
        static from(raw, _ctx) {
            const hasStarted = raw.payload[0] !== 0;
            return new this({
                hasStarted,
            });
        }
        isOK() {
            return this.hasStarted;
        }
        hasStarted;
        toLogEntry() {
            return {
                ...super.toLogEntry(),
                message: { "has started": this.hasStarted },
            };
        }
    };
    return AssignPriorityReturnRouteResponse = _classThis;
})();
export { AssignPriorityReturnRouteResponse };
export class AssignPriorityReturnRouteRequestTransmitReport extends AssignPriorityReturnRouteRequestBase {
    constructor(options) {
        super(options);
        this.callbackId = this.payload[0];
        this.transmitStatus = this.payload[1];
    }
    static from(raw, _ctx) {
        const callbackId = raw.payload[0];
        const transmitStatus = raw.payload[1];
        return new this({
            callbackId,
            transmitStatus,
        });
    }
    isOK() {
        // The other statuses are technically "not OK", but they are caused by
        // not being able to contact the node. We don't want the node to be marked
        // as dead because of that
        return this.transmitStatus !== TransmitStatus.NoAck;
    }
    transmitStatus;
    toLogEntry() {
        return {
            ...super.toLogEntry(),
            message: {
                "callback id": this.callbackId ?? "(not set)",
                "transmit status": getEnumMemberName(TransmitStatus, this.transmitStatus),
            },
        };
    }
}
//# sourceMappingURL=AssignPriorityReturnRouteMessages.js.map