"use strict";
// -*- mode: typescript; indent-tabs-mode: nil; js-basic-offset: 4 -*-
//
// This file is part of Genie
//
// Copyright 2020 The Board of Trustees of the Leland Stanford Junior University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: Giovanni Campagna <gcampagn@cs.stanford.edu>
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const assert_1 = __importDefault(require("assert"));
const I18n = __importStar(require("../../i18n"));
const random_1 = require("../../utils/random");
const requoting_1 = require("../requoting");
/**
  Augmentation pass that adds "ask ..." prefixes to single-device commands.
*/
class SingleDeviceAugmenter {
    constructor(locale, thingpediaClient, expandFactor, rng) {
        assert_1.default(typeof expandFactor === 'number');
        assert_1.default(expandFactor > 0);
        this._tpClient = thingpediaClient;
        this._templates = I18n.get(locale).SINGLE_DEVICE_TEMPLATES;
        this._expandFactor = Math.min(expandFactor, this._templates.length);
        this._rng = rng;
        this._deviceNames = new Map;
        this._init = this._doInit();
    }
    async _doInit() {
        const names = await this._tpClient.getAllDeviceNames();
        for (const row of names)
            this._deviceNames.set(row.kind, row.kind_canonical);
    }
    async process(ex) {
        await this._init;
        if (this._expandFactor < 1)
            return [];
        if (ex.context && ex.context !== 'null')
            return [];
        const devices = new Set(requoting_1.getDevices(ex.target_code, ['@org.thingpedia.builtin.thingengine.builtin.say']));
        if (devices.size > 1 || devices.size <= 0)
            return [];
        // yay, it's a single-device command
        const exampleDevice = Array.from(devices)[0];
        // remove the "@" at the beginning
        const deviceName = this._deviceNames.get(exampleDevice.substring(1));
        if (!deviceName)
            return [];
        const validTemplates = this._templates.filter(([tmpl, condition]) => {
            return condition === null || condition.test(ex.preprocessed);
        });
        const chosenTemplates = random_1.choose(validTemplates, this._expandFactor, this._rng);
        return chosenTemplates.map(([tmpl,]) => {
            const newUtterance = tmpl.split(' ').map((word) => {
                if (word === '$device')
                    return deviceName;
                else if (word === '$command')
                    return ex.preprocessed;
                else
                    return word;
            }).join(' ');
            const flags = {};
            if (ex.flags)
                Object.assign(flags, ex.flags);
            flags.augmented = true;
            return {
                id: ex.id,
                flags: flags,
                type: ex.type,
                utterance: newUtterance,
                preprocessed: newUtterance,
                context: ex.context,
                target_code: ex.target_code
            };
        });
    }
}
exports.default = SingleDeviceAugmenter;
//# sourceMappingURL=single_device_augmenter.js.map