"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const crypto = require("crypto");
const WebSocket = require("@oznu/ws-connect");
const logger_1 = require("./logger");
const hap_1 = require("./hap");
class Plugin {
    constructor(log, config, homebridgeConfig) {
        this.log = new logger_1.Log(log, config.debug);
        this.config = config;
        this.homebridgeConfig = homebridgeConfig;
        const deviceId = crypto.createHash('sha256')
            .update(this.homebridgeConfig.bridge.username)
            .digest('hex');
        const socket = new WebSocket(`wss://homebridge-gsh.iot.oz.nu/socket?token=${config.token}&deviceId=${deviceId}`);
        this.hap = new hap_1.Hap(socket, this.log, this.homebridgeConfig.bridge.pin, this.config);
        socket.on('websocket-status', (status) => {
            this.log.info(status);
        });
        socket.on('json', (req) => __awaiter(this, void 0, void 0, function* () {
            if (!req.body.inputs) {
            }
            const res = (response) => {
                socket.sendJson({
                    type: 'response',
                    requestId: req.requestId,
                    body: response,
                });
            };
            if (!this.hap.ready) {
                this.log.info('Devices Not Ready');
                return res(this.deviceNotReady(req.body));
            }
            for (const input of req.body.inputs) {
                input.requestId = req.body.requestId;
                switch (input.intent) {
                    case 'action.devices.SYNC':
                        setTimeout(() => {
                            this.log.debug('Sending full post-sync state report');
                            this.hap.sendFullStateReport();
                        }, 10000);
                        return res(yield this.onSync(req.body));
                    case 'action.devices.QUERY':
                        return res(yield this.onQuery(req.body));
                    case 'action.devices.EXECUTE':
                        return res(yield this.onExecute(req.body));
                    case 'action.devices.DISCONNECT':
                        return res(yield this.onDisconnect(req.body));
                    default:
                        this.log.error(`ERROR - Unknown Intent: ${input.intent}`);
                        break;
                }
            }
        }));
    }
    onSync(body) {
        return __awaiter(this, void 0, void 0, function* () {
            this.log.info('Received SYNC intent');
            this.log.debug(JSON.stringify(body, null, 2));
            const devices = yield this.hap.buildSyncResponse();
            this.log.debug(devices);
            return {
                requestId: body.requestId,
                payload: {
                    agentUserId: null,
                    devices,
                },
            };
        });
    }
    onQuery(body) {
        return __awaiter(this, void 0, void 0, function* () {
            this.log.info('Received QUERY intent');
            this.log.debug(JSON.stringify(body, null, 2));
            const devices = yield this.hap.query(body.inputs[0].payload.devices);
            this.log.debug(devices);
            return {
                requestId: body.requestId,
                payload: {
                    devices,
                },
            };
        });
    }
    onExecute(body) {
        return __awaiter(this, void 0, void 0, function* () {
            this.log.info('Received EXECUTE intent');
            this.log.debug(JSON.stringify(body, null, 2));
            const commands = yield this.hap.execute(body.inputs[0].payload.commands);
            this.log.debug(commands);
            return {
                requestId: body.requestId,
                payload: {
                    commands,
                },
            };
        });
    }
    onDisconnect(body) {
        return __awaiter(this, void 0, void 0, function* () {
            this.log.info('Received DISCONNECT intent');
            this.log.debug(JSON.stringify(body, null, 2));
            return {
                requestId: body.requestId,
                payload: {},
            };
        });
    }
    deviceNotReady(body) {
        return {
            requestId: body.requestId,
            payload: {
                errorCode: 'deviceNotReady',
                status: 'ERROR',
            },
        };
    }
}
exports.Plugin = Plugin;
//# sourceMappingURL=main.js.map