/**
 * Onvif module
 * @author Andrew D.Laptev <a.d.laptev@gmail.com>
 * @see https://www.onvif.org/wp-content/uploads/2022/07/ONVIF_Device_Feature_Discovery_Specification_21.12.pdf
 */
import { EventEmitter } from 'events';
import { SecureContextOptions } from 'tls';
import { Agent as HttpsAgent, RequestOptions } from 'https';
import http, { Agent as HttpAgent } from 'http';
import { OnvifResponse } from './utils';
import Device from './device';
import type Media from './media';
import type Media2 from './media2';
import type PTZ from './ptz';
import { Capabilities, Profile, SystemDateTime } from './interfaces/onvif';
import { GetDeviceInformationResponse, SetSystemDateAndTime } from './interfaces/devicemgmt';
import { ReferenceToken } from './interfaces/common';
import Events, { NotificationMessage } from './events';
import type Replay from './replay';
import type Imaging from './imaging';
import type Recording from './recording';
import type DoorControl from './doorcontrol';
import type AccessControl from './accesscontrol';
import type Credential from './credential';
import type AccessRules from './accessrules';
import type Schedule from './schedule';
import type Provisioning from './provisioning';
import type AdvancedSecurity from './advancedsecurity';
import type Thermal from './thermal';
import type Analytics from './analytics';
import type DeviceIO from './deviceio';
import type Display from './display';
import type ActionEngine from './actionengine';
import type Search from './search';
import type AnalyticsDevice from './analyticsdevice';
import type Receiver from './receiver';
/**
 * Cam constructor options
 */
export interface OnvifOptions {
    /** Set true if using `https` protocol, defaults to false. */
    useSecure?: boolean;
    /** Set options for https like ca, cert, ciphers, rejectUnauthorized, secureOptions, secureProtocol, etc. */
    secureOptions?: SecureContextOptions;
    /** Use WS-Security SOAP headers */
    useWSSecurity?: boolean;
    hostname: string;
    username?: string;
    password?: string;
    port?: number;
    path?: string;
    timeout?: number;
    urn?: string;
    /** Supports things like https://www.npmjs.com/package/proxy-agent which provide SOCKS5 and other connections. */
    agent?: HttpsAgent | HttpAgent | boolean;
    /** Force using hostname and port from constructor for the services (ex.: for proxying), defaults to false. */
    preserveAddress?: boolean;
    /** Set false if the camera should not connect automatically, defaults false. */
    autoConnect?: boolean;
}
export interface OnvifServices {
    ptz?: URL;
    analytics?: URL;
    analyticsdevice?: URL;
    device?: URL;
    deviceIO?: URL;
    display?: URL;
    events?: URL;
    imaging?: URL;
    media2?: URL;
    media?: URL;
    receiver?: URL;
    recording?: URL;
    replay?: URL;
    doorcontrol?: URL;
    accesscontrol?: URL;
    credential?: URL;
    accessrules?: URL;
    schedule?: URL;
    provisioning?: URL;
    advancedsecurity?: URL;
    thermal?: URL;
    actionengine?: URL;
    search?: URL;
    [key: string]: URL | undefined;
}
export interface OnvifRequestOptions extends Omit<RequestOptions, 'headers'> {
    headers?: http.OutgoingHttpHeaders;
    /** Name of service (ptz, media, etc) */
    service?: keyof OnvifServices;
    /** SOAP body */
    body: Record<string, any>;
    /** Defines another url to request */
    url?: URL;
    /** Make request to PTZ uri or not */
    ptz?: boolean;
    /** Timeout for pull-point event requests */
    timeout?: number;
    /** Additional SOAP-headers */
    soapHeaders?: Record<string, any>;
    /** Tags that should be forced to be arrays */
    array?: string[];
    /** Values of these tags will be in xml2js format */
    rawXML?: string[];
}
export interface OnvifRawRequestOptions extends Omit<OnvifRequestOptions, 'body'> {
    /** SOAP body */
    body: string;
}
/**
 * Information about active video source
 */
export interface ActiveSource {
    sourceToken: ReferenceToken;
    /**
     * Media profile token
     */
    profileToken: ReferenceToken;
    videoSourceConfigurationToken: ReferenceToken;
    videoSourceToken: ReferenceToken;
    encoding?: string;
    width?: number;
    height?: number;
    fps?: number;
    bitrate?: number;
    ptz?: {
        name: string;
        token: ReferenceToken;
    };
}
export interface SetSystemDateAndTimeExtended extends SetSystemDateAndTime {
    /**
     * Javascript Date object to use instead of UTCDateTime
     */
    dateTime?: Date;
    /**
     * The TZ format is specified by POSIX, please refer to POSIX 1003.1 section 8.3
     * Example: Europe, Paris TZ=CET-1CEST,M3.5.0/2,M10.5.0/3
     * CET = designation for standard time when daylight saving is not in force
     * -1 = offset in hours = negative so 1 hour east of Greenwich meridian
     * CEST = designation when daylight saving is in force ("Central European Summer Time")
     * , = no offset number between code and comma, so default to one hour ahead for daylight saving
     * M3.5.0 = when daylight saving starts = the last Sunday in March (the "5th" week means the last in the month)
     * /2, = the local time when the switch occurs = 2 a.m. in this case
     * M10.5.0 = when daylight saving ends = the last Sunday in October.
     * /3, = the local time when the switch occurs = 3 a.m. in this case
     */
    timezone?: string;
}
export interface SystemDateTimeExtended extends SystemDateTime {
    /**
     * Javascript Date object to use instead of UTCDateTime
     */
    dateTime: Date;
}
interface OnvifEvents {
    [Onvif.EVENT]: [msg: NotificationMessage];
    [Onvif.ERROR]: [error: Error];
    [Onvif.CONNECT]: [];
    [Onvif.RAW_REQUEST]: [xml: string, requestOptions: http.RequestOptions];
    [Onvif.REQUEST_BODY]: [body: string];
    [Onvif.RAW_RESPONSE]: [xml: string];
    [Onvif.WARN]: [error: Error];
    [Onvif.EVENTS_ERROR]: [error: Error];
    newListener: [event: string, listener: (...args: any[]) => void];
    removeListener: [event: string, listener: (...args: any[]) => void];
}
export declare class Onvif extends EventEmitter<OnvifEvents> {
    /**
     * Indicates raw xml response from device.
     * @event rawResponse
     * @example
     * ```typescript
     * onvif.on('rawResponse', (xml) => { console.log('<- response was', xml); });
     * ```
     */
    static readonly RAW_RESPONSE = "rawResponse";
    /**
     * Indicates raw xml request to device.
     * @event rawRequest
     * @example
     * ```typescript
     * onvif.on('rawRequest', (xml) => { console.log('-> request was', xml); });
     * ```
     */
    static readonly RAW_REQUEST = "rawRequest";
    /**
     * Shows body of request
     * @event
     */
    static readonly REQUEST_BODY = "requestBody";
    /**
     * Indicates any errors except events errors
     * @event error
     * @example
     * ```typescript
     * onvif.on('error', console.error);
     * ```
     */
    static readonly ERROR = "error";
    /**
     * Indicates events errors
     * @event eventsError
     * @example
     * ```typescript
     * onvif.on('eventsError', console.error);
     * ```
     */
    static readonly EVENTS_ERROR = "eventsError";
    /**
     * Indicates any event from Onvif device.
     * @event event
     * @example
     * ```typescript
     * onvif.on('event', (msg) => { console.log(new Date().toLocaleTimeString(), 'new event', msg); });
     * ```
     */
    static readonly EVENT = "event";
    /**
     * Indicates any warnings
     * @event warn
     * @example
     * ```typescript
     * onvif.on('warn', console.warn);
     * ```
     */
    static readonly WARN = "warn";
    /**
     * Indicates successfully connection
     * @event connect
     * @example
     * ```typescript
     * onvif.on('connect', () => console.log('connected!'));
     * ```
     */
    static readonly CONNECT = "connect";
    /**
     * Core device namespace for device v1.0 methods
     * @example
     * ```typescript
     * const date = await onvif.device.getSystemDateAndTime();
     * console.log(date.toLocaleString());
     * ```
     */
    readonly device: Device;
    /**
     * Media namespace for media v1.0 methods
     * @example
     * ```typescript
     * const profiles = await onvif.media.getProfiles();
     * console.log(profiles);
     * ```
     */
    readonly media: Media;
    /**
     * Media2 namespace for media2 v1.0 methods
     * @example
     * ```typescript
     * const profiles = await onvif.media2.getProfiles();
     * console.log(profiles);
     * ```
     */
    readonly media2: Media2;
    /**
     * PTZ namespace for ptz v1.0 methods
     * @example
     * ```typescript
     * const ptz = await onvif.ptz.getPTZStatus();
     * console.log(ptz);
     * ```
     */
    readonly ptz: PTZ;
    /**
     * Events namespace for events v1.0 methods
     * @example
     * ```typescript
     * onvif.on('event', (msg) => { console.log('-> request was', xml); });
     * ```
     */
    readonly events: Events;
    /**
     * Replay namespace for replay v1.0 methods
     * @example
     * ```typescript
     * const replay = await onvif.replay.getReplayConfiguration();
     * console.log(replay);
     * ```
     */
    readonly replay: Replay;
    /**
     * Imaging namespace for imaging v1.0 methods
     * @example
     * ```typescript
     * const imaging = await onvif.imaging.getImagingSettings();
     * console.log(imaging);
     * ```
     */
    readonly imaging: Imaging;
    /**
     * Recording namespace for recording v1.0 methods
     * @example
     * ```typescript
     * const recording = await onvif.recording.getRecordingConfiguration();
     * console.log(recording);
     * ```
     */
    readonly recording: Recording;
    /**
     * DoorControl namespace for doorcontrol v1.0 methods
     * @example
     * ```typescript
     * const doorControl = await onvif.doorControl.getDoorControlConfiguration();
     * console.log(doorControl);
     * ```
     */
    readonly doorControl: DoorControl;
    /**
     * AccessControl namespace for accesscontrol v1.0 methods
     * @example
     * ```typescript
     * const list = await onvif.accessControl.getAccessPointInfoList();
     * console.log(list);
     * ```
     */
    readonly accessControl: AccessControl;
    /**
     * Credential namespace for credential v1.0 methods
     * @example
     * ```typescript
     * const list = await onvif.credential.getCredentialInfoList();
     * console.log(list);
     * ```
     */
    readonly credential: Credential;
    /**
     * AccessRules namespace for accessrules v1.0 methods
     * @example
     * ```typescript
     * const list = await onvif.accessRules.getAccessProfileInfoList();
     * console.log(list);
     * ```
     */
    readonly accessRules: AccessRules;
    /**
     * Schedule namespace for schedule v1.0 methods
     * @example
     * ```typescript
     * const list = await onvif.schedule.getScheduleInfoList();
     * console.log(list);
     * ```
     */
    readonly schedule: Schedule;
    /**
     * Provisioning namespace for provisioning v1.0 methods
     * @example
     * ```typescript
     * const caps = await onvif.provisioning.getServiceCapabilities();
     * console.log(caps);
     * ```
     */
    readonly provisioning: Provisioning;
    /**
     * AdvancedSecurity namespace for advancedsecurity v1.0 methods
     * @example
     * ```typescript
     * const caps = await onvif.advancedSecurity.getServiceCapabilities();
     * console.log(caps);
     * ```
     */
    readonly advancedSecurity: AdvancedSecurity;
    /**
     * Thermal namespace for thermal v1.0 methods
     * @example
     * ```typescript
     * const thermal = await onvif.thermal.getConfigurations();
     * console.log(thermal);
     * ```
     */
    readonly thermal: Thermal;
    /**
     * Analytics namespace for analytics v1.0 methods
     * @example
     * ```typescript
     * const analytics = await onvif.analytics.getAnalyticsConfiguration();
     * console.log(analytics);
     * ```
     */
    readonly analytics: Analytics;
    /**
     * DeviceIO namespace for deviceio v1.0 methods
     * @example
     * ```typescript
     * const deviceIO = await onvif.deviceIO.getDeviceIOConfiguration();
     * console.log(deviceIO);
     * ```
     */
    readonly deviceIO: DeviceIO;
    /**
     * Display namespace for display v1.0 methods
     * @example
     * ```typescript
     * const display = await onvif.display.getDisplayConfiguration();
     * console.log(display);
     * ```
     */
    readonly display: Display;
    /**
     * ActionEngine namespace for actionengine v1.0 methods
     * @example
     * ```typescript
     * const actionEngine = await onvif.actionEngine.getActionEngineConfiguration();
     * console.log(actionEngine);
     * ```
     */
    readonly actionEngine: ActionEngine;
    /**
     * Search namespace for search v1.0 methods
     * @example
     * ```typescript
     * const summary = await onvif.search.getRecordingSummary();
     * console.log(summary);
     * ```
     */
    readonly search: Search;
    /**
     * AnalyticsDevice namespace for analytics device v1.0 methods
     * @example
     * ```typescript
     * const controls = await onvif.analyticsDevice.getAnalyticsEngineControls();
     * console.log(controls);
     * ```
     */
    readonly analyticsDevice: AnalyticsDevice;
    /**
     * Receiver namespace for receiver v1.0 methods
     * @example
     * ```typescript
     * const receivers = await onvif.receiver.getReceivers();
     * console.log(receivers);
     * ```
     */
    readonly receiver: Receiver;
    /**
     * Indicates if the device is using secure connection
     */
    readonly useSecure: boolean;
    /**
     * Secure options for the connection
     */
    secureOptions: SecureContextOptions;
    /**
     * Use WS-Security for the connection (this is the default and adds security headers in the SOAP messages)
     */
    useWSSecurity: boolean;
    /**
     * Nonce for the connection
     */
    private nc;
    /**
     * Hostname of the ONVIF device
     */
    hostname: string;
    /**
     * Username for the connection
     */
    username?: string;
    /**
     * Password for the connection
     */
    password?: string;
    /**
     * Port for the connection
     */
    port: number;
    /**
     * Path for the connection
     */
    path: string;
    timeout: number;
    agent: HttpsAgent | HttpAgent | boolean;
    preserveAddress: boolean;
    uri: OnvifServices;
    private timeShift?;
    capabilities: Capabilities;
    defaultProfiles: Profile[];
    defaultProfile?: Profile;
    private activeSources;
    activeSource?: ActiveSource;
    readonly urn?: string;
    deviceInformation?: GetDeviceInformationResponse;
    constructor(options: OnvifOptions);
    envelopeBody(body: Record<string, any>): {
        $: {
            'xmlns:xsi': string;
            'xmlns:xsd': string;
        };
    };
    /**
     * Envelope header for all SOAP messages
     * @param options
     * @private
     */
    envelopeHeader(options?: OnvifRequestOptions): {
        Security?: {
            $: {
                's:mustUnderstand': string;
                xmlns: string;
            };
            UsernameToken: {
                Username: string | undefined;
                Password: {
                    $: {
                        Type: string;
                    };
                    _: string;
                };
                Nonce: {
                    $: {
                        EncodingType: string;
                    };
                    _: string;
                };
                Created: {
                    $: {
                        xmlns: string;
                    };
                    _: string;
                };
            };
        } | undefined;
    };
    private passwordDigest;
    private rawRequest;
    private digestAuth;
    request(options: OnvifRequestOptions): OnvifResponse;
    private parseChallenge;
    private updateNC;
    /**
     * Parse url with an eye on `preserveAddress` property
     * @param address
     * @private
     */
    parseUrl(address: string): URL;
    /**
     * Receive date and time from cam
     */
    getSystemDateAndTime(): Promise<SystemDateTimeExtended>;
    /**
     * Receive only date and time from cam (old behaviour, returns only Date object)
     */
    getOnlySystemDateAndTime(): Promise<Date>;
    /**
     * Add time shift to use with ONVIF timestamps
     * @param data
     * @private
     */
    private setupSystemDateAndTime;
    /**
     * Set the device system date and time
     * Supports two possible date and time values: UTCDateTime(ONVIF types) or dateTime(js Date-object, preferred)
     */
    setSystemDateAndTime(options: SetSystemDateAndTimeExtended): Promise<SystemDateTimeExtended>;
    /**
     * Check and find out video configuration for device
     * @private
     */
    private getActiveSources;
    /**
     * Connect to the camera and fill device information properties
     */
    connect(): Promise<this>;
}
export {};
