"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 ThingTalk = __importStar(require("thingtalk"));
const Tp = __importStar(require("thingpedia"));
const qs_1 = __importDefault(require("qs"));
const exactbuilder_1 = __importDefault(require("./exactbuilder"));
class RemoteParserClient {
    constructor(baseUrl, locale, platform, tpClient) {
        this._locale = locale;
        this._baseUrl = baseUrl + '/' + this._locale;
        this._platform = platform;
        this._tpClient = tpClient;
    }
    async start() {
        if (!this._platform || !this._tpClient)
            return;
        const prefs = this._platform.getSharedPreferences();
        const developerDir = prefs.get('developer-dir');
        if (!developerDir)
            return;
        const builder = new exactbuilder_1.default({
            locale: this._locale,
            timezone: this._platform.timezone,
            cachedir: this._platform.getCacheDir(),
            developerdir: Array.isArray(developerDir) ? developerDir : [developerDir],
            thingpediaClient: this._tpClient,
        });
        this._exactmatcher = await builder.load();
    }
    async stop() {
    }
    async onlineLearn(utterance, code, store = 'automatic') {
        const data = {
            q: utterance,
            target: code.join(' '),
            store: store,
            thingtalk_version: ThingTalk.version,
        };
        if (this._platform)
            data.developer_key = this._platform.getDeveloperKey();
        let result;
        try {
            result = await Tp.Helpers.Http.post(this._baseUrl + '/learn', qs_1.default.stringify(data), { dataContentType: 'application/x-www-form-urlencoded' });
            console.log('Sent "' + utterance + '" to Almond-NNParser for learning');
        }
        catch (e) {
            console.error('Failed to send "' + utterance + '" to Almond-NNParser for learning: ' + e.message);
        }
        return result;
    }
    async sendUtterance(utterance, contextCode, contextEntities, options = {}) {
        const data = {
            q: utterance,
            store: options.store || 'no',
            thingtalk_version: ThingTalk.version,
            tokenized: options.tokenized,
            skip_typechecking: options.skip_typechecking
        };
        if (contextCode !== undefined) {
            data.context = contextCode.join(' ');
            data.entities = contextEntities;
        }
        if (this._platform)
            data.developer_key = this._platform.getDeveloperKey();
        if (options.expect)
            data.expect = String(options.expect);
        if (options.choices)
            data.choices = options.choices;
        if (options.answer)
            data.answer = options.answer;
        const response = await Tp.Helpers.Http.post(`${this._baseUrl}/query`, JSON.stringify(data), {
            dataContentType: 'application/json' //'
        });
        const parsed = JSON.parse(response);
        if (parsed.error)
            throw new Error('Error received from NLP server: ' + parsed.error);
        if (this._exactmatcher && data.expect !== 'MultipleChoice') {
            const exact = this._exactmatcher.get(parsed.tokens);
            if (exact)
                parsed.candidates = exact.map((code) => ({ code, score: 'Infinity' })).concat(parsed.candidates);
        }
        return parsed;
    }
    async generateUtterance(contextCode, contextEntities, targetAct) {
        const data = {
            context: contextCode.join(' '),
            entities: contextEntities,
            target: targetAct.join(' ')
        };
        const response = await Tp.Helpers.Http.post(`${this._baseUrl}/answer`, JSON.stringify(data), {
            dataContentType: 'application/json' //'
        });
        const parsed = JSON.parse(response);
        if (parsed.error)
            throw new Error('Error received from Genie server: ' + parsed.error);
        return parsed.candidates;
    }
}
exports.default = RemoteParserClient;
//# sourceMappingURL=remoteparserclient.js.map