import { Logger } from 'homebridge';
import { Checker, ITypeSuite, TType } from 'ts-interface-checker';
import { LocalStorage } from 'node-persist';
import { CommandValues, EventMapValues, OptionValues, ProgramKey, SettingValues, StatusValues } from './api-value-types.js';
import { Command, Constraints, ConstraintsCommon, EventApplianceConnection, EventApplianceData, EventData, HomeAppliance, Option, OptionConstraintsCommon, OptionDefinition, OptionDefinitionCommon, Program, ProgramDefinition, ProgramList, Programs, Setting, SettingCommon, Status, StatusCommon, Value } from './api-types.js';
import { APIEvent, EventStart, EventStop } from './api-events.js';
import { ConfigPlugin } from './config-types.js';
export type KVKey<Values> = keyof Values;
export type CommandKey = KVKey<CommandValues>;
export type OptionKey = KVKey<OptionValues>;
export type StatusKey = KVKey<StatusValues>;
export type SettingKey = KVKey<SettingValues>;
export type EventMapKey = KVKey<EventMapValues>;
export type EventKey<Event extends EventMapKey = EventMapKey> = Event extends Event ? KVKey<EventMapValues[Event]> : never;
export type KVValue<Values, Key> = Key extends keyof Values ? Required<Values>[Key] : never;
export type CommandValue<Key> = KVValue<CommandValues, Key>;
export type OptionValue<Key> = KVValue<OptionValues, Key>;
export type StatusValue<Key> = KVValue<StatusValues, Key>;
export type SettingValue<Key> = KVValue<SettingValues, Key>;
export type EventValue<Key, Event extends EventMapKey = EventMapKey> = Event extends Event ? KVValue<EventMapValues[Event], Key> : never;
interface ConstraintsForType<Type> extends ConstraintsCommon {
    default?: Type;
    min?: MapValueType<Type, number, never, never, never>;
    max?: MapValueType<Type, number, never, never, never>;
    stepsize?: MapValueType<Type, number, never, never, never>;
    allowedvalues?: MapValueType<Type, never, never, never, EnumType<Type>[]>;
    displayvalues?: MapValueType<Type, never, never, never, string[]>;
}
type MapValueType<Type, IsNumber, IsBoolean, IsString, IsEnum> = Type extends number ? IsNumber : (Type extends boolean ? IsBoolean : (string extends Type ? IsString : IsEnum));
type EnumType<Type> = Type extends string ? (string extends Type ? never : Type) : never;
type ExtendKV<Super, Sub> = Sub & Omit<Super, keyof Sub>;
export interface CommandKV extends Command {
    key: CommandKey;
}
export interface ProgramsKV extends Programs {
    programs: ProgramListKV[];
    selected?: Partial<ProgramKV>;
    active?: Partial<ProgramKV>;
}
export interface ProgramListKV extends ProgramList {
    key: ProgramKey;
}
export interface ProgramKV extends Program {
    key: ProgramKey;
    options?: OptionKV[];
}
export interface ProgramDefinitionKV<PKey extends ProgramKey = ProgramKey> extends Omit<ProgramDefinition, 'options'> {
    key: PKey;
    options?: OptionDefinitionKV[];
}
export type OptionDefinitionKV<KeyU extends OptionKey = OptionKey> = {
    [Key in KeyU]: ExtendKV<OptionDefinitionCommon, {
        key: Key;
        type: OptionTypeForType<OptionValue<Key>>;
        constraints?: OptionConstraintsCommon & ConstraintsForType<OptionValue<Key>>;
    }>;
}[KeyU];
type OptionTypeForType<Type> = MapValueType<Type, 'Double' | 'Int', 'Boolean', 'String', string>;
export type OptionKV<KeyU extends OptionKey = OptionKey> = {
    [Key in KeyU]: ExtendKV<Option, {
        key: Key;
        value: OptionValue<Key>;
    }>;
}[KeyU];
export type StatusKV<KeyU extends StatusKey = StatusKey> = {
    [Key in KeyU]: ExtendKV<StatusCommon, {
        key: Key;
        value: StatusValue<Key>;
        constraints?: ConstraintsForType<StatusValue<Key>>;
    }>;
}[KeyU];
export type SettingKV<KeyU extends SettingKey = SettingKey> = {
    [Key in KeyU]: ExtendKV<SettingCommon, {
        key: Key;
        value: SettingValue<Key>;
        constraints?: ConstraintsForType<SettingValue<Key>>;
    }>;
}[KeyU];
export type EventKV = EventApplianceConnectionKV | EventApplianceDataKV | EventStart | EventStop;
export type EventApplianceConnectionEvent = EventApplianceConnection['event'];
export type EventApplianceConnectionKV<EventU extends EventApplianceConnectionEvent = EventApplianceConnectionEvent> = {
    [Event in EventU]: ExtendKV<EventApplianceConnection, {
        event: Event;
        data?: '' | EventDataKV<Event>;
    }>;
}[EventU];
export type EventApplianceDataEvent = EventApplianceData['event'];
export type EventApplianceDataKV<EventU extends EventApplianceDataEvent = EventApplianceDataEvent> = {
    [Event in EventU]: ExtendKV<EventApplianceData, {
        event: Event;
        data: Omit<EventApplianceData['data'], 'items'> & {
            items: EventDataKV<Event>[];
        };
    }>;
}[EventU];
export type EventDataKV<EventU extends EventMapKey = EventMapKey, KeyU extends EventKey<EventU> = EventKey<EventU>> = {
    [Event in EventU]: {
        [Key in KeyU]: ExtendKV<EventData, {
            key: Key;
            value: EventValue<Key, Event>;
        }>;
    }[KeyU];
}[EventU];
export interface APICheckValueContext {
    haid: string;
    group: string;
    subGroup?: string;
    type?: string;
    json: object;
    keyFailed?: boolean;
}
export declare class APICheckValues {
    readonly log: Logger;
    readonly config: ConfigPlugin;
    readonly persist: LocalStorage;
    private readonly nextKeyReport;
    private readonly logValues;
    constructor(log: Logger, config: ConfigPlugin, persist: LocalStorage);
    appliances(appliances: HomeAppliance[]): HomeAppliance[];
    appliance(haid: string, appliance: HomeAppliance): HomeAppliance;
    programs(haid: string, programs: Programs): ProgramsKV;
    programDefinition<PKey extends ProgramKey>(haid: string, program: ProgramDefinition): ProgramDefinitionKV<PKey>;
    program(haid: string, program: Program, type?: string): ProgramKV;
    options(haid: string, options: Option[]): OptionKV[];
    option<Key extends OptionKey>(haid: string, option: Option): OptionKV<Key>;
    optionDefinitions(haid: string, options: OptionDefinition[]): OptionDefinitionKV[];
    optionDefinition<Key extends OptionKey>(haid: string, option: OptionDefinition): OptionDefinitionKV<Key>;
    statuses(haid: string, status: Status[]): StatusKV[];
    status<Key extends StatusKey>(haid: string, status: Status): StatusKV<Key>;
    settings(haid: string, settings: Setting[]): SettingKV[];
    setting<Key extends SettingKey>(haid: string, setting: Setting): SettingKV<Key>;
    commands(haid: string, commands: Command[]): CommandKV[];
    event(haid: string, event: APIEvent): EventKV;
    isLiteral(checker: Checker, context: APICheckValueContext, literal: string): boolean;
    isKey(typeSuite: ITypeSuite, checkerType: TType, context: APICheckValueContext, key: string): boolean;
    isConstraints(checker: Checker, context: APICheckValueContext, key: string, constraints?: Constraints): boolean;
    isValue(checker: Checker, context: APICheckValueContext, key: string, value: Value | null): boolean;
    logValidation(message: string, name: string, json: object, details: string[]): void;
}
export {};
//# sourceMappingURL=api-value.d.ts.map