/// <reference types="node" />
/// <reference types="node" />
import { Db, ChangeStream } from "mongodb";
import { TokenUser, Base, mapFunc, finalizeFunc, reduceFunc, UpdateOneMessage, UpdateManyMessage, InsertOrUpdateOneMessage, Role, User, QueryOptions, CountOptions } from "@openiap/openflow-api";
import { ObservableUpDownCounter, Histogram } from "@opentelemetry/api-metrics";
import { Span } from "@opentelemetry/api";
import events = require("events");
import { clsstream } from "./WebSocketServerClient";
export declare type GetDocumentVersionOptions = {
    collectionname: string;
    id: string;
    version: number;
    jwt?: string;
    decrypt?: boolean;
};
export declare type GetLatestDocumentVersionOptions = {
    collectionname: string;
    id: string;
    jwt?: string;
    decrypt?: boolean;
};
export declare class DatabaseConnection extends events.EventEmitter {
    private mongodburl;
    private cli;
    db: Db;
    private _dbname;
    static mongodb_query: Histogram;
    static mongodb_count: Histogram;
    static mongodb_aggregate: Histogram;
    static mongodb_insert: Histogram;
    static mongodb_insertmany: Histogram;
    static mongodb_update: Histogram;
    static mongodb_updatemany: Histogram;
    static mongodb_replace: Histogram;
    static mongodb_delete: Histogram;
    static mongodb_deletemany: Histogram;
    static mongodb_active_sessions: ObservableUpDownCounter;
    registerGlobalWatches: boolean;
    queuemonitoringhandle: NodeJS.Timeout;
    queuemonitoringpaused: boolean;
    queuemonitoringlastrun: Date;
    constructor(mongodburl: string, dbname: string, registerGlobalWatches: boolean);
    static toArray(iterator: any): Promise<any[]>;
    isConnected: boolean;
    shutdown(): Promise<void>;
    replicat: string;
    streams: clsstream[];
    /**
     * Connect to MongoDB
     * @returns Promise<void>
     */
    connect(parent?: Span): Promise<void>;
    queuemonitoring(): Promise<void>;
    queuemonitoring_old(): Promise<void>;
    registerGlobalWatch(collectionname: string, parent: Span): boolean;
    ListCollections(jwt: string): Promise<any[]>;
    DropCollection(collectionname: string, jwt: string, parent: Span): Promise<void>;
    WellknownIdsArray: string[];
    WellknownNamesArray: string[];
    CleanACL<T extends Base>(item: T, user: TokenUser, collection: string, parent: Span): Promise<T>;
    Cleanmembers<T extends Role>(item: T, original: T): Promise<T>;
    /**
     * Send a query to the database.
     * @param {any} query MongoDB Query
     * @param {Object} projection MongoDB projection
     * @param {number} top Limit result to X number of results
     * @param {number} skip Skip a number of records (Paging)
     * @param {Object|string} orderby MongoDB orderby, or string with name of a single field to orderby
     * @param {string} collectionname What collection to query
     * @param {string} jwt JWT of user who is making the query, to limit results based on permissions
     * @param {boolean} decrypt Decrypt encrypted data, default: true
     * @returns Promise<T[]> Array of results
     */
    query<T extends Base>(options: QueryOptions, parent: Span): Promise<T[]>;
    /**
     * Send a query to the database.
     * @param {any} query MongoDB Query
     * @param {string} collectionname What collection to query
     * @param {string} jwt JWT of user who is making the query, to limit results based on permissions
     * @returns Promise<T[]> Array of results
     */
    count(options: CountOptions, parent: Span): Promise<number>;
    GetLatestDocumentVersion<T extends Base>(options: GetLatestDocumentVersionOptions, parent: Span): Promise<T>;
    GetDocumentVersion<T extends Base>(options: GetDocumentVersionOptions, parent: Span): Promise<T>;
    /**
 * Get a single item based on id
 * @param  {string} id Id to search for
 * @param  {string} collectionname Collection to search
 * @param  {string} jwt JWT of user who is making the query, to limit results based on permissions
 * @returns Promise<T>
 */
    GetOne<T extends Base>(options: {
        query?: object;
        collectionname: string;
        orderby?: object;
        jwt?: string;
        decrypt?: boolean;
    }, parent: Span): Promise<T>;
    /**
     * Get a single item based on id
     * @param  {string} id Id to search for
     * @param  {string} collectionname Collection to search
     * @param  {string} jwt JWT of user who is making the query, to limit results based on permissions
     * @returns Promise<T>
     */
    getbyid<T extends Base>(id: string, collectionname: string, jwt: string, decrypt: boolean, parent: Span): Promise<T>;
    /**
     * Get a single item based on username
     * @param  {string} username Username to search for
     * @param  {string} collectionname Collection to search
     * @param  {string} jwt JWT of user who is making the query, to limit results based on permissions
     * @returns Promise<T>
     */
    getbyusername<T extends Base>(username: string, issuer: string, jwt: string, decrypt: boolean, parent: Span): Promise<T>;
    /**
     * Do MongoDB aggregation
     * @param  {any} aggregates
     * @param  {string} collectionname
     * @param  {string} jwt
     * @returns Promise
     */
    aggregate<T extends Base>(aggregates: object[], collectionname: string, jwt: string, hint: Object | string, parent: Span): Promise<T[]>;
    /**
     * Do MongoDB watch
     * @param  {any} aggregates
     * @param  {string} collectionname
     * @param  {string} jwt
     * @returns Promise
     */
    watch<T extends Base>(aggregates: object[], collectionname: string, jwt: string): Promise<ChangeStream>;
    /**
     * Do MongoDB map reduce
     * @param  {any} aggregates
     * @param  {string} collectionname
     * @param  {string} jwt
     * @returns Promise
     */
    MapReduce<T>(map: mapFunc, reduce: reduceFunc, finalize: finalizeFunc, query: any, out: string | any, collectionname: string, scope: any, jwt: string): Promise<T[]>;
    /**
     * Create a new document in the database
     * @param  {T} item Item to create
     * @param  {string} collectionname The collection to create item in
     * @param  {number} w Write Concern ( 0:no acknowledgment, 1:Requests acknowledgment, 2: Requests acknowledgment from 2, 3:Requests acknowledgment from 3)
     * @param  {boolean} j Ensure is written to the on-disk journal.
     * @param  {string} jwt JWT of the user, creating the item, to ensure rights and permission
     * @returns Promise<T> Returns the new item added
     */
    InsertOne<T extends Base>(item: T, collectionname: string, w: number, j: boolean, jwt: string, parent: Span): Promise<T>;
    InsertMany<T extends Base>(items: T[], collectionname: string, w: number, j: boolean, jwt: string, parent: Span): Promise<T[]>;
    /**
     * Update entity in database
     * @param  {T} item Item to update
     * @param  {string} collectionname Collection containing item
     * @param  {number} w Write Concern ( 0:no acknowledgment, 1:Requests acknowledgment, 2: Requests acknowledgment from 2, 3:Requests acknowledgment from 3)
     * @param  {boolean} j Ensure is written to the on-disk journal.
     * @param  {string} jwt JWT of user who is doing the update, ensuring rights
     * @returns Promise<T>
     */
    _UpdateOne<T extends Base>(query: any, item: T, collectionname: string, w: number, j: boolean, jwt: string, parent: Span): Promise<T>;
    UpdateOne<T extends Base>(q: UpdateOneMessage, parent: Span): Promise<UpdateOneMessage>;
    /**
    * Update multiple documents in database based on update document
    * @param {any} query MongoDB Query
    * @param  {T} item Update document
    * @param  {string} collectionname Collection containing item
    * @param  {number} w Write Concern ( 0:no acknowledgment, 1:Requests acknowledgment, 2: Requests acknowledgment from 2, 3:Requests acknowledgment from 3)
    * @param  {boolean} j Ensure is written to the on-disk journal.
    * @param  {string} jwt JWT of user who is doing the update, ensuring rights
    * @returns Promise<T>
    */
    UpdateDocument<T extends Base>(q: UpdateManyMessage, parent: Span): Promise<UpdateManyMessage>;
    static Semaphore: (n: any) => {
        n: any;
        down(): Promise<void>;
        up(): void;
        wait(): Promise<unknown>;
    };
    InsertOrUpdateOne<T extends Base>(q: InsertOrUpdateOneMessage, parent: Span): Promise<InsertOrUpdateOneMessage>;
    private static InsertOrUpdateOneSemaphore;
    /**
    * Insert or Update depending on document allready exists.
    * @param  {T} item Item to insert or update
    * @param  {string} collectionname Collection containing item
    * @param  {string} uniqeness List of fields to combine for uniqeness
    * @param  {number} w Write Concern ( 0:no acknowledgment, 1:Requests acknowledgment, 2: Requests acknowledgment from 2, 3:Requests acknowledgment from 3)
    * @param  {boolean} j Ensure is written to the on-disk journal.
    * @param  {string} jwt JWT of user who is doing the update, ensuring rights
    * @returns Promise<T>
    */
    _InsertOrUpdateOne<T extends Base>(q: InsertOrUpdateOneMessage, parent: Span): Promise<InsertOrUpdateOneMessage>;
    InsertOrUpdateMany<T extends Base>(items: T[], collectionname: string, uniqeness: string, skipresults: boolean, w: number, j: boolean, jwt: string, parent: Span): Promise<T[]>;
    private _DeleteFile;
    /**
     * @param  {string} id id of object to delete
     * @param  {string} collectionname collectionname Collection containing item
     * @param  {string} jwt JWT of user who is doing the delete, ensuring rights
     * @returns Promise<void>
     */
    DeleteOne(id: string | any, collectionname: string, recursive: boolean, jwt: string, parent: Span): Promise<void>;
    /**
     * @param  {string} id id of object to delete
     * @param  {string} collectionname collectionname Collection containing item
     * @param  {string} jwt JWT of user who is doing the delete, ensuring rights
     * @returns Promise<void>
     */
    DeleteMany(query: string | any, ids: string[], collectionname: string, queryas: string, recursive: boolean, jwt: string, parent: Span): Promise<number>;
    /**
     * Helper function used to check if field needs to be encrypted
     * @param  {string[]} keys List of fields that needs to be encrypted
     * @param  {string} key Current field
     * @param  {object=null} value value of field, ensuring we can actully encrypt the field
     * @returns boolean
     */
    private _shouldEncryptValue;
    /**
     * Enumerate object, encrypting fields that needs to be encrypted
     * @param  {T} item Item to enumerate
     * @returns T Object with encrypted fields
     */
    encryptentity(item: Base): Base;
    /**
     * Enumerate object, decrypting fields that needs to be decrypted
     * @param  {T} item Item to enumerate
     * @returns T Object with decrypted fields
     */
    decryptentity<T extends Base>(item: T): T;
    /**
     * Create a MongoDB query filtering result based on permission of current user and requested permission
     * @param  {string} jwt JWT of the user creating the query
     * @param  {number[]} bits Permission wanted on objects
     * @returns Object MongoDB query
     */
    getbasequery(user: TokenUser | User, field: string, bits: number[]): Object;
    private getbasequeryuserid;
    /**
     * Ensure _type and _acs on object
     * @param  {T} item Object to validate
     * @returns T Validated object
     */
    ensureResource<T extends Base>(item: T, collection: string): T;
    EntityRestrictions: EntityRestriction[];
    loadEntityRestrictions(parent: Span): Promise<void>;
    CheckEntityRestriction(user: TokenUser, collection: string, item: Base, parent: Span): Promise<boolean>;
    /**
     * Validated user has rights to perform the requested action ( create is missing! )
     * @param  {TokenUser} user User requesting permission
     * @param  {any} item Item permission is needed on
     * @param  {Rights} action Permission wanted (create, update, delete)
     * @returns boolean Is allowed
     */
    static hasAuthorization(user: TokenUser, item: Base, action: number): boolean;
    static replaceAll(target: any, search: any, replacement: any): any;
    /**
     * Helper function to clean item before saving in MongoDB ( normalize ACE rights and remove illegal key $$ )
     * @param  {object} o Item to clean
     * @returns void Clean object
     */
    static traversejsonencode(o: any): void;
    static traversejsondecode(o: any): void;
    SaveUpdateDiff<T extends Base>(q: UpdateOneMessage, user: TokenUser, parent: Span): Promise<number>;
    visit(obj: any, func: any): void;
    SaveDiff(collectionname: string, original: any, item: any, parent: Span): Promise<number>;
    createIndex(collectionname: string, name: string, keypath: any, options: any, parent: Span): Promise<unknown>;
    deleteIndex(collectionname: string, name: string, parent: Span): Promise<unknown>;
    static collections_with_text_index: string[];
    static timeseries_collections: string[];
    ensureindexes(parent: Span): Promise<void>;
    static usemetadata(collectionname: string): boolean;
    static otel_label(collectionname: string, user: TokenUser | User, action: "query" | "count" | "aggregate" | "insert" | "insertmany" | "update" | "updatemany" | "replace" | "delete" | "deletemany"): {
        collection: string;
        username: string;
    } | {
        collection: string;
        username?: undefined;
    };
}
export declare class EntityRestriction extends Base {
    collection: string;
    copyperm: boolean;
    paths: string[];
    constructor();
    static assign<EntityRestriction>(o: any): EntityRestriction;
    IsMatch(object: object): boolean;
    IsAuthorized(user: TokenUser | User): boolean;
}
