import * as ThingTalk from 'thingtalk';
import * as Tp from 'thingpedia';
import DeviceDatabase from './devices/database';
import TierManager from './tiers/tier_manager';
import AppDatabase from './apps/database';
import type AppExecutor from './apps/app_executor';
import AssistantDispatcher from '../dialogue-agent/dispatcher';
import { FormattedChunk } from '../dialogue-agent/card-output/text-formatter';
/**
 * Information about a running ThingTalk program (app).
 * @typedef {Object} AppInfo
 * @property {string} uniqueId - the unique ID of the app
 * @property {string} name - a short string identifying the app
 * @property {string} description - a longer description of the code in the app
 * @property {string|null} icon - the icon associated with the app (as a Thingpedia class ID)
 * @property {boolean} isRunning - whether the app is currently running (executing ThingTalk code)
 * @property {boolean} isEnabled - whether the app is set to run in the background
 * @property {string|null} error - the last error reported by the app
 */
export interface AppInfo {
    uniqueId: string;
    name: string;
    description: string;
    code: string;
    icon: string | null;
    isRunning: boolean;
    isEnabled: boolean;
    error: string | null;
}
/**
 * Information about a configured Thingpedia device.
 * @typedef {Object} DeviceInfo
 * @property {string} uniqueId - the unique ID of the device
 * @property {string} name - a short, human-readable string identifying the device
 * @property {string} description - a longer string describing the device
 * @property {string} kind - the Thingpedia class ID this device belongs to (suitable to select an icon)
 * @property {number} version - the version of the class this device belongs to
 * @property {string} class - the coarse categorization of the device: `physical`, `online`, `data`, or `system`
 * @property {string} ownerTier - the ID of the engine that configured this device (for purposes of cloud sync)
 * @property {boolean} isTransient - true if this device was created on the fly by some discovery module, false
 *           if it was configured manually and is stored on disk
 */
export interface DeviceInfo {
    uniqueId: string;
    name: string;
    description: string;
    kind: string;
    version: number;
    class: 'physical' | 'online' | 'data' | 'system';
    ownerTier: string;
    isTransient: boolean;
}
interface DeviceState {
    kind: string;
    accessToken?: string;
    refreshToken?: string;
    [key: string]: unknown;
}
interface AssistantEngineOptions {
    cloudSyncUrl?: string;
    nluModelUrl?: string;
    thingpediaUrl?: string;
}
interface CreateAppOptions {
    uniqueId?: string;
    name?: string;
    description?: string;
    icon?: string;
    conversation?: string;
}
interface AppResult {
    raw: Record<string, unknown>;
    type: string;
    formatted: FormattedChunk[];
}
/**
 * The core Genie engine.
 *
 * There is one engine instance per user. Multiple engine instances
 * can run in the same process, but they must be associated with
 * different platform objects.
 *
 * @extends external:thingpedia.BaseEngine
 */
export default class AssistantEngine extends Tp.BaseEngine {
    readonly _: (x: string) => string;
    _tiers: TierManager;
    private _modules;
    private _devices;
    private _appdb;
    private _assistant;
    private _running;
    private _stopCallback;
    /**
     * Construct a new engine.
     *
     * @param {external:thingpedia.BasePlatform} platform - the platform associated with this engine
     * @param {Object} options - additional options; this is also passed to the parent class
     * @param {string} [options.cloudSyncUrl] - URL to use for cloud sync
     */
    constructor(platform: Tp.BasePlatform, options?: AssistantEngineOptions);
    /**
     * Return a unique identifier associated with this engine.
     *
     * This is a string composed of two parts: the high-level tier type
     * (phone, cloud, server, desktop), and a unique identifier. The tier
     * is used by the cloud sync subsystem, and can be used by devices
     * that use local communication to distinguish which engine configured them.
     */
    get ownTier(): string;
    /**
     * Access the device database of this engine.
     */
    get devices(): DeviceDatabase;
    /**
     * Access the app database of this engine.
     */
    get apps(): AppDatabase;
    /**
     * Access the assistant dispatcher of this engine.
     */
    get assistant(): AssistantDispatcher;
    private _openSequential;
    private _closeSequential;
    /**
     * Initialize this engine.
     *
     * This will initialize all modules sequentially in the right
     * order. It must be called before {@link Engine#run}.
     */
    open(): Promise<void>;
    /**
     * Deinitialize this engine.
     *
     * This will sequentially close all modules, save the database
     * and release all resources.
     *
     * This should not be called if {@link Engine#start} fails. After
     * this method succeed, the engine is in undefined state and must
     * not be used.
     */
    close(): Promise<void>;
    /**
     * Run ThingTalk rules.
     *
     * Kick start the engine by returning a promise that will
     * run each rule in sequence, forever, without ever being
     * fulfilled until {@link Engine#stop} is called.
     */
    run(): Promise<void>;
    /**
     * Stop any rule execution at the next available moment.
     *
     * This will cause the {@link Engine#run} promise to be fulfilled.
     *
     * This method can be called multiple times and is idempotent.
     * It can also be called before {@link Engine#run}.
     */
    stop(): void;
    /**
     * Begin configuring a device with an OAuth-like flow.
     *
     * @param {string} kind - the Thingpedia class ID of the device to configure.
     * @return {Array} a tuple with the redirect URL and the session object.
     * @async
     */
    startOAuth(kind: string): Promise<[string, Record<string, string>]>;
    /**
     * Complete OAuth-like configuration for a device.
     *
     * @param {string} kind - the Thingpedia class ID of the device to configure.
     * @param {string} redirectUri - the OAuth redirect URI that was called at the end of the OAuth flow.
     * @param {Object.<string,string>} session - an object with session information.
     * @return {external:thingpedia.BaseDevice} the configured device
     * @async
     */
    completeOAuth(kind: string, redirectUri: string, session: Record<string, string>): Promise<Tp.BaseDevice>;
    /**
     * Configure a simple device with no configuration information needed.
     *
     * @param {string} kind - the Thingpedia class ID of the device to configure.
     * @return {external:thingpedia.BaseDevice} the configured device
     * @async
     */
    createSimpleDevice(kind: string): Promise<Tp.BaseDevice>;
    /**
     * Configure a device with direct configuration information.
     *
     * @param {Object} state - the configured device parameters.
     * @param {string} state.kind - the Thingpedia class ID of the device to configure.
     * @return {external:thingpedia.BaseDevice} the configured device
     * @async
     */
    createDevice(state: DeviceState): Promise<Tp.BaseDevice>;
    /**
     * Delete a device by ID.
     *
     * Deleting a device removes any stored credentials and configuration about that device.
     *
     * @param {string} uniqueId - the ID of the device to delete
     * @return {boolean} true if the device was deleted successfully, false if it did not exist
     */
    deleteDevice(uniqueId: string): Promise<boolean>;
    /**
     * Update all devices of the given type to the latest version in Thingpedia.
     *
     * @param {string} kind - the Thingpedia class ID of the devices to update
     */
    upgradeDevice(kind: string): Promise<void>;
    /**
     * Returns the list of all device classes that have been previously cached.
     */
    getCachedDeviceClasses(): Promise<any[]>;
    /**
     * Returns whether a specific device has been configured or not.
     *
     * @param {string} uniqueId - the device ID to check
     * @return {boolean} true if the device exists, false otherwise
     */
    hasDevice(uniqueId: string): boolean;
    private _toDeviceInfo;
    /**
     * Get information about all configured devices.
     *
     * @param {string} [kind] - filter only devices that have the specified kind
     * @return {Array<DeviceInfo>} a list of device info objects, one per device
     */
    getDeviceInfos(kind: string): DeviceInfo[];
    /**
     * Get information about one configured device by ID.
     *
     * @param {string} uniqueId - the ID of the device to return info for
     * @return information about that device
     */
    getDeviceInfo(uniqueId: string): DeviceInfo;
    /**
     * Asynchronously check whether a device is available.
     *
     * @param {string} uniqueId - the ID of the device to check
     * @return {external:thingpedia.Availability} whether the device is available
     * @async
     */
    checkDeviceAvailable(uniqueId: string): Promise<Tp.Availability>;
    private _toAppInfo;
    /**
     * Get information about all running ThingTalk programs (apps).
     *
     * @return {Array<AppInfo>} a list of app info objects, one per app
     */
    getAppInfos(): AppInfo[];
    /**
     * Get information about one running ThingTalk program (app) by ID.
     *
     * @param {string} uniqueId - the ID of the app to return info for
     * @param {boolean} [throw_=true] - throw an error if there is no such app
     * @return {AppInfo} information about that app
     */
    getAppInfo(uniqueId: string, throw_?: true): AppInfo;
    getAppInfo(uniqueId: string, throw_: boolean): AppInfo | undefined;
    /**
     * Stop (delete) the ThingTalk program (app) with the given ID.
     *
     * @param {string} uniqueId - the ID of the app to delete
     * @return {boolean} true if the deletion occurred, false otherwise
     */
    deleteApp(uniqueId: string): Promise<boolean>;
    /**
     * Create a new ThingTalk app.
     *
     * This is the main entry point to execute ThingTalk code.
     *
     * @param {string|external:thingtalk.Ast.Program} program - the ThingTalk code to execute,
     *        or the parsed ThingTalk program (AST)
     * @param {Object} options
     * @param {string} [options.uniqueId] - the ID to assign to the new app
     * @param {string} [options.name] - the name of the new app
     * @param {string} [options.description] - the human-readable description of the code
     *        being executed
     * @param {string} [options.icon] - the icon of the new app (as a Thingpedia class ID)
     * @param {string} [options.conversation] - the ID of the conversation associated with the new app
     * @return {AppExecutor} the newly created program
     */
    createApp(programOrString: ThingTalk.Ast.Program | string, options?: CreateAppOptions): Promise<AppExecutor>;
    /**
     * Create a new ThingTalk app, and execute it to compute all results.
     *
     * This is a convenience wrapper over {@link Engine#createApp} that also
     * iterates the results of the app and formats them.
     *
     * @param {string|external:thingtalk.Ast.Program} program - the ThingTalk code to execute,
     *        or the parsed ThingTalk program (AST)
     * @param {Object} options
     * @param {string} [options.uniqueId] - the ID to assign to the new app
     * @param {string} [options.name] - the name of the new app
     * @param {string} [options.description] - the human-readable description of the code
     *        being executed
     * @param {string} [options.icon] - the icon of the new app (as a Thingpedia class ID)
     * @param {string} [options.conversation] - the ID of the conversation associated with the new app
     */
    createAppAndReturnResults(programOrString: ThingTalk.Ast.Program | string, options?: CreateAppOptions): Promise<{
        uniqueId: string;
        description: string;
        code: string;
        icon: string | null;
        results: AppResult[];
        errors: Error[];
    }>;
    /**
     * Configure cloud synchronization.
     *
     * This method can be called in non-cloud Almond to start synchronization
     * with the cloud.
     *
     * @param {string} cloudId - the ID of the user in Web Almond
     * @param {string} authToken - the access token
     */
    setCloudId(cloudId: string, authToken: string): Promise<boolean>;
    /**
     * Configure synchronization with a local server.
     *
     * This method can be called in a phone or desktop Almond to synchronize
     * with a locally-setup home server Almond .
     *
     * @param {string} serverHost - the IP address or hostname of the server to connect to
     * @param {number} serverPort - the port at which server is reachable
     * @param {string} authToken - the access token
     */
    addServerAddress(serverHost: string, serverPort: number, authToken: string): Promise<boolean>;
}
export {};
