"use strict";
// -*- mode: typescript; indent-tabs-mode: nil; js-basic-offset: 4 -*-
//
// This file is part of Genie
//
// Copyright 2018 Google LLC
//           2018-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 __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getBestEntityMatch = exports.collectDisambiguationHints = void 0;
const assert_1 = __importDefault(require("assert"));
const thingtalk_1 = require("thingtalk");
const edit_distance_1 = __importDefault(require("../../utils/edit-distance"));
// FIXME use the actual tokenizer
function tokenize(string) {
    const tokens = string.split(/(\s+|[,."'!?])/g);
    return tokens.filter((t) => !(/^\s*$/).test(t)).map((t) => t.toLowerCase());
}
function collectDisambiguationHints(result, idEntities, previousLocations) {
    for (const key in result.value) {
        const value = result.value[key];
        if (previousLocations && value instanceof thingtalk_1.Ast.LocationValue && value.value instanceof thingtalk_1.Ast.AbsoluteLocation)
            previousLocations.push(value.value);
        if (key === 'id') {
            const id = result.value.id;
            if (!(id instanceof thingtalk_1.Ast.EntityValue) || !id.display)
                continue;
            const idType = id.type;
            const idEntity = {
                value: id.value,
                name: id.display,
                canonical: tokenize(id.display).join(' ')
            };
            if (idEntities.has(idType))
                idEntities.get(idType).push(idEntity);
            else
                idEntities.set(idType, [idEntity]);
        }
    }
}
exports.collectDisambiguationHints = collectDisambiguationHints;
function getBestEntityMatch(searchTerm, entityType, candidates) {
    let best = undefined, bestScore = undefined;
    const refinedSearchTerm = removeParenthesis(searchTerm);
    const searchTermTokens = refinedSearchTerm.split(' ');
    for (const cand of candidates) {
        const candDisplay = removeParenthesis(cand.canonical);
        let score = 0;
        score -= 0.1 * edit_distance_1.default(refinedSearchTerm, candDisplay);
        const candTokens = new Set(candDisplay.split(' '));
        for (const candToken of candTokens) {
            let found = false;
            for (const token of searchTermTokens) {
                if (token === candToken || (edit_distance_1.default(token, candToken) <= 1 && token.length > 1)) {
                    score += 10;
                    found = true;
                }
                else if (candToken.startsWith(token)) {
                    score += 0.5;
                }
            }
            // give a small boost to ignorable tokens that are missing
            // this offsets the char-level edit distance
            if (!found && ['the', 'hotel', 'house', 'restaurant'].includes(candToken))
                score += 0.1 * (1 + candToken.length); // add 1 to account for the space
            if (entityType === 'imgflip:meme_id' && candToken === 'x')
                score += 1;
        }
        //console.log(`candidate ${cand.name} score ${score}`);
        if (bestScore === undefined || score > bestScore) {
            bestScore = score;
            best = cand;
        }
    }
    assert_1.default(best);
    return best;
}
exports.getBestEntityMatch = getBestEntityMatch;
function removeParenthesis(str) {
    return str.replace(/ \(.*?\)/g, '');
}
//# sourceMappingURL=entity-finder.js.map