export type CanThrowOn =
    | 'geolocationPermissionDenied'
    | 'geolocationTimeout'
    | 'geolocationPositionUnavailable';

export interface GeolocationOptions {
    /**
     * Whether to enable geolocation or not.
     *
     * Default: false
     */
    enabled?: boolean;
    /**
     * Enables high accuracy for the Geolocation API. It might slightly increase the fingerprinting
     * time.
     *
     * Default: true
     */
    highAccuracy?: boolean;
    /**
     * Controls whether the SDK can generate a geolocation permission prompt in the browser. The
     * access to the Geolocation API in the browser is restricted, and only allowed when a user
     * explicitly grants permission. By default the SEON SDK does not interrupt the user flow in any
     * way, so it will not prompt users, but this also means that if geolocation permission was not
     * granted to the site by other means, the geolocation information will be missing from the
     * result.
     *
     * Additionally, if a prompt is given to the user, the SDK will stall until the user either
     * grants or denies the permission. This means that the 'getSession' Promise might hang for a
     * longer time, effectively increasing the time it takes to fingerprint a user's browser.
     *
     * Default: false
     */
    canPrompt?: boolean;
    /**
     * The Geolocation API can return cached data. This option controls the maximum age in seconds
     * of a cached position that is acceptable to return. If set to 0, it means that the device
     * cannot use a cached position and must attempt to retrieve the real current position.
     *
     * Default: 0
     */
    maxAgeSeconds?: number;
    /**
     * **Note: This option is only considered if 'canPrompt' is true.**
     *
     * Timeout for the Geolocation API to return the position of the device. This timeout is
     * measured from when the user grants the permission to the page (or from the `getSession` call
     * if the permission was already given).
     *
     * This option can be set to `Infinity`. In this case the SDK won't return until the position is
     * available.
     *
     * This timeout only works if 'canPrompt' is enabled. This option is only necessary because
     * waiting for the user to grant or deny permission takes indefinite amount of time. If
     * 'canPrompt' is not enabled then the global timeout applies to the geolocation field as well,
     * so this option will have no effect.
     *
     * Default: 1000
     */
    timeoutMs?: number;
}

export interface SDKOptions {
    /**
     * It is recommended to set this option to the closest supported region of your user base to
     * reduce the runtime of fingerprinting.
     *
     * Supported regions:
     *
     * - "eu"
     *
     * Default: "eu"
     */
    region?: string;
    /**
     * The domain to use for DNS checks. You might need to change this domain to one of our
     * alternative domains to avoid adblockers. Please note that if your site uses CSP headers, then
     * you must set a 'connect-src' directive to allow requests to this domain and all subdomains.
     *
     * **Note: The default value is subject to change between minor versions in order for us to keep
     * a default value that is not blacklisted. If this behavior is undesirable for you, please set
     * this option explicitly.**
     *
     * Supported domains:
     *
     * - "seondnsresolve.com"
     * - "seondfresolver.com"
     * - "deviceinfresolver.com"
     * - "getdeviceinfresolver.com"
     * - "seonintelligenceresolver.com"
     *
     * Default: "seondnsresolve.com"
     */
    dnsResolverDomain?: string;
    /** Options for the geolocation feature */
    geolocation?: GeolocationOptions;
    /**
     * Timeout for the network call in milliseconds.
     *
     * For the most accurate device fingerprinting results we utilize network requests to our
     * services. This option sets the maximum time that the SDK will wait for the response of these
     * requests.
     *
     * It is advisable to increase this timeout if some detections (especially the proxy and vpn) do
     * not always return consistent result.
     *
     * Default: 2000
     */
    networkTimeoutMs?: number;
    /**
     * Global timeout for the fingerprinting in milliseconds.
     *
     * This option **can** limit the maximum runtime of the fingerprinting. It is recommended to
     * primarily rely on this option, rather than wrapping the 'getSession' call in a timeout,
     * because this way a partial result is still generated in case of a timeout.
     *
     * There are some caveats to setting this option:
     *
     * - When reaching the specified timeout, the SDK will stop all pending checks, and return all
     *   device details that have already been collected. So in case of a timeout, the SDK will
     *   still generate an output, but it might only be a partial one.
     * - This is not a hard limit. Setting this value to a very low value (e.g. 100 ms) will probably
     *   still result in response times greater than the defined value because some internal
     *   operations must always complete for a valid result. The recommended minimum value is
     *   2000ms.
     * - Setting 'geolocation.canPrompt' to true and 'geolocation.timeout' will always force the SDK
     *   to wait for the user to either grant or deny the permission prompt (if given). Thus in this
     *   case the fingerprinting runtime will depend on the geolocation collection except when it
     *   finishes faster than the defined 'fieldTimeoutMs'
     * - If the 'networkTimeoutMs' is greater than this option, and the network request is still
     *   pending when the defined timeout occurs, then the 'networkTimeoutMs' will be honored and
     *   the network request will still be awaited (until 'networkTimeoutMs').
     *
     * Default: 5000
     */
    fieldTimeoutMs?: number;
    /**
     * A list of possible causes for the SDK to throw an error.
     *
     * By default the SDK only throws an error for an invalid 'options' object, but otherwise always
     * runs to completion.
     *
     * In some cases it might be desirable to throw an error when specific conditions are met during
     * execution. E.g. due to legal requirements you must collect geolocation data from users on
     * your site. If a user denies geolocation permission then you would have to wait for the
     * fingerprinting, send the result the SEON, await the result, and then block access to the user
     * because they denied the geolocation prompt. This would be inconvenient, so instead you can
     * define that in the event of a user denying the geolocation permission, the SDK should throw a
     * JavaScript error indicating the issue.
     *
     * Possible values:
     *
     * - "geolocationPermissionDenied" -> throws SEONGeolocationPermissionDenied error if the
     *   geolocation permission prompt is denied
     * - "geolocationTimeout" -> throws SEONGeolocationTimeout error if the geolocation request times
     *   out
     * - "geolocationPositionUnavailable" -> throws SEONGeolocationPositionUnavailable error if the
     *   position is unavailable
     *
     * Default: []
     */
    throwOn?: CanThrowOn[];
    /**
     * Configuration of the window_location property that will be included in the results.
     *
     * The location field could be very large for long URLs, which would mean the generated session
     * string would also be too large. To mitigate this, there's a maximum allowed length for this
     * field. The inclusion of the URL's search params are disabled by default but can be enabled.
     *
     * Default: { maxLength: 128, searchParams: false }
     */
    windowLocation?: URLStringConfig;
    /**
     * Configuration of the referrer property that will be included in the results.
     *
     * The referrer field could be very large for long URLs, which would mean the generated session
     * string would also be too large. To mitigate this, there's a maximum allowed length for this
     * field. The inclusion of the URL's search params are disabled by default but can be enabled.
     *
     * Default: { maxLength: 128, searchParams: false }
     */
    referrer?: URLStringConfig;
    /**
     * Whether to allow the JavaScript SDK to trigger warnings and errors on the DevTools console.
     * Turning this off will allow the SDK to create a more accurate fingerprint.
     *
     * Note: the user experience will not be degraded, warnings will only be generated on the
     * developer tools console.
     *
     * Default: true
     */
    silentMode?: boolean;
    /**
     * If defined, it appends the consentId string to the generated session string. Can be used for
     * specific integrations that relied on this for previous versions, but should be ignored for
     * most use cases.
     *
     * If undefined or empty string, nothing will be appended. Maximum string length: 128 characters
     *
     * Default: empty string
     */
    consentId?: string;
    /**
     * Enable experimental feature to detect hardware acceleration. It will increase the generated
     * session size by about 10%.
     *
     * Default: false
     */
    experimentalHardwareAccelerationDetection?: boolean;
}

export interface URLStringConfig {
    /**
     * Maximum length of the URL.
     *
     * Default: 128, Allowed range: 0-1024
     */
    maxLength: number;
    /**
     * Whether to include search parameters of the URL.
     *
     * Default: false
     */
    searchParams: boolean;
}

export interface SDKInitOptions {
    /** Settings for the behavioral biometrics data collection */
    behavioralDataCollection?: BehaviorCollectionOptions;
}

export interface BehaviorCollectionOptions {
    /**
     * QuerySelector string that selects the targets for which the behavior biometrics should be
     * enabled.
     *
     * If left undefined, it will track behavior on the whole page. To disable this feature, specify
     * an empty string.
     *
     * Default: undefined
     */
    targets?: string;
    /**
     * Selects the form by its element ID to measure the fillout time. Only the first matching
     * element is considered.
     *
     * If left undefined, this datapoint will not be available.
     *
     * Default: undefined
     */
    formFilloutDurationTargetId?: string;
}

export type getSessionFunction = (options?: SDKOptions) => Promise<string>;
export type initFunction = (initOptions?: SDKInitOptions) => void;

declare const _default: {
    /**
     * Initializes the SDK and some internal event listeners.
     *
     * This function should be called on page load with an optional initOptions object. As such it
     * is lightweight and shouldn't affect load times much. Calling this function is not required
     * but recommended.
     *
     * @param [initOptions] - Init configuration options
     */
    init: initFunction;
    /**
     * Collects the device fingerprint of the browser.
     *
     * It is recommended to call this function on a user action, e.g. on a form submit. The 'init'
     * function should also be called before this one for a more accurate fingerprint. This is an
     * optional but recommended step.
     *
     * @example
     *     // On page load:
     *     seon.init();
     *     // Later on when the fingerprint is needed:
     *     const session = await seon.getSession();
     *     // 'session' variable holds the encrypted device fingerprint that should be sent to SEON
     *
     * @param [options] - Configuration options for the SDK
     * @returns A Promise that resolves to the encrypted device fingerprint as a base64 encoded
     *   string
     */
    getSession: getSessionFunction;
};

export default _default;