import { Ast } from 'thingtalk';
import type Engine from '../engine';
import type { DeviceInfo } from '../engine';
import ValueCategory from './value-category';
import StatementExecutor from './statement_executor';
import { EntityRecord } from './entity-linking/entity-finder';
import { Contact } from './entity-linking/contact_search';
import { PlatformData } from './user-input';
import AbstractDialogueAgent, { DisambiguationHints } from './abstract_dialogue_agent';
/**
 * The interface that the {@link ExecutionDialogueAgent} uses to communicate
 * with outside.
 *
 * In some code paths, {@link ExecutionDialogueAgent} needs to send messages
 * to the user or ask questions, in the middle of preparing for execution
 * and outside of the normal dialogue loop.
 *
 * It does so by calling this interface, which for the normal assistant is
 * implemented by {@link DialogueLoop}.
 *
 * TODO: This interface has some ugly inversion of control where the outside
 * code that drives the dialogue gets called synchronously by this code.
 * We should refactor all of this.
 */
export interface AbstractDialogueLoop {
    icon: string | null;
    platformData: PlatformData;
    isAnonymous: boolean;
    _: (x: string) => string;
    reply(msg: string): Promise<void>;
    replyLink(title: string, link: string): Promise<void>;
    interpolate(msg: string, args: Record<string, unknown>): string;
    replyInterp(msg: string, args: Record<string, unknown>): Promise<void>;
    ask(expected: ValueCategory.PhoneNumber | ValueCategory.EmailAddress | ValueCategory.Location | ValueCategory.Time, question: string, args?: Record<string, unknown>): Promise<Ast.Value>;
    askChoices(question: string, choices: string[]): Promise<number>;
}
/**
 * The execution time dialogue agent.
 *
 * Provides access to the real user's information, stored in the engine.
 */
export default class ExecutionDialogueAgent extends AbstractDialogueAgent<undefined> {
    private _engine;
    private _thingpedia;
    private _platform;
    private _dlg;
    private _executor;
    constructor(engine: Engine, dlg: AbstractDialogueLoop, debug: boolean);
    get _(): (x: string) => string;
    get executor(): StatementExecutor;
    getAllDevicesOfKind(kind: string): DeviceInfo[];
    disambiguate(type: 'device' | 'contact', name: string | null, choices: string[], hint?: string): Promise<number>;
    protected tryConfigureDevice(kind: string): Promise<DeviceInfo | null>;
    lookupContact(category: ValueCategory, name: string): Promise<Contact[]>;
    askMissingContact(category: ValueCategory.EmailAddress | ValueCategory.PhoneNumber | ValueCategory.Contact, name: string): Promise<Ast.EntityValue>;
    protected addDisplayToContact(contact: Ast.EntityValue): Promise<void>;
    private _constructEntityQuery;
    protected lookupEntityCandidates(entityType: string, entityDisplay: string, hints: DisambiguationHints): Promise<EntityRecord[]>;
    private _tryGetCurrentLocation;
    protected lookupLocation(searchKey: string, previousLocations: Ast.AbsoluteLocation[]): Promise<Ast.LocationValue>;
    private _tryGetStoredVariable;
    protected resolveUserContext(variable: string): Promise<Ast.Value>;
    getPreferredUnit(type: string): string | undefined;
}
