const CacheProviders = ['none', 'redis', 'memory', 'level'] as const

export type CacheProvider = (typeof CacheProviders)[number]

export interface ICacheDBConfig {
	provider: CacheProvider
	redisSettings?: {
		instance: any
		url: string
		password: string
		database: number
	}
	levelSettings?: {
		instance: any
		database: string
	}
}

export interface ICacheStorageConfig {
	module: ICacheStorage
	dbParams?: ICacheDBConfig
	isBrowser: boolean
	useCache?: boolean
}

export interface ICacheStorage {
	/**
	 * Configure the cache storage
	 * @param {ICacheStorageConfig} config
	 * @returns {Promise<void>}
	 * @description
	 * 	- config (general) is the configuration object
	 * 	- config.module is the module instance
	 * 	- config.dbInstance is the database instance
	 * 	- config.isBrowser is a boolean to indicate if the cache storage is running in a browser
	 */
	config: (config: ICacheStorageConfig) => Promise<void>
	/**
	 * Add data to the cache storage
	 * @param {string} key
	 * @param {T} data
	 * @param {number} expiration
	 * @returns {Promise<void>}
	 * @description
	 * 	- key is the key to store the data under
	 * 	- data is the data to store
	 * 	- expiration is the time of life for the data (in seconds)
	 */
	addData: <T>(key: string, data: T, expiration?: number) => Promise<void>
	/**
	 * Get data from the cache storage
	 * @param {string} key
	 * @returns {Promise<T>}
	 * @description
	 * 	- key is the key to retrieve the data from
	 * 	- data is the data retrieved
	 */
	getData: <T>(key: string) => Promise<T | undefined>
	/**
	 * Update data in the cache storage
	 * @param {string} key
	 * @param {T} data
	 * @returns {Promise<void>}
	 * @description
	 * 	- key is the key to update the data under
	 * 	- data is the data to update
	 * 	- expiration is the time of life for the data (in seconds)
	 */
	updateData: <T>(key: string, data: T, expiration?: number) => Promise<void>
	/**
	 * Remove data from the cache storage
	 * @param {string} key
	 * @returns {Promise<void>}
	 * @description
	 * 	- key is the key to remove the data from
	 * 	- data is the data removed
	 */
	removeData: (key: string) => Promise<void>
	/**
	 * Remove data from the cache storage
	 * @param {string} pattern
	 * @returns {Promise<void>}
	 * @description
	 * 	- pattern is the pattern to remove the data
	 *  example: key stored is 'my-data-123-test' then the pattern to remove it is '123'
	 */
	removeDataByPattern?: (pattern: string) => Promise<void>
	/**
	 * Reset the cache storage
	 * @returns {Promise<void>}
	 * @description
	 * 	- method to remove all data from the cache storage and delete the database
	 */
	resetData: () => Promise<void>
}
