/*************************************************************************
* ADOBE CONFIDENTIAL
* ___________________
*
*  Copyright 2015 Adobe Systems Incorporated
*  All Rights Reserved.
*
* NOTICE:  All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any.  The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and are protected by all applicable intellectual property laws,
* including trade secret and or copyright laws.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/
import{loggingApi as e}from"./loggingApi.js";import{dcLocalStorage as r}from"./local-storage.js";const t=new class{usageMetricsIntervalMinutes=10080;cleanupIntervalMinutes=10080;constructor(){this.dbName="AnalyticsDatabase",this.dbVersion=1,this.dbStoreName="analyticsSendState",this.ready=this.openDatabase(),this._isARFEnabled().then(e=>{e&&(this.createAlarmForUsageMetrics(),this.createCleanupAlarm())})}async _isARFEnabled(){return await r.init(),"true"===r.getItem("arfEnabled")}_clearAlarms(){chrome.alarms.clear("analyticsCleanupAlarm"),chrome.alarms.clear("analyticsInstrumentationAlarm")}createCleanupAlarm(){chrome.alarms.get("analyticsCleanupAlarm").then(e=>{e||chrome.alarms.create("analyticsCleanupAlarm",{periodInMinutes:this.cleanupIntervalMinutes})}),chrome.alarms.onAlarm.addListener(this.cleanupAlarmHandler.bind(this))}async cleanupAlarmHandler(e){"analyticsCleanupAlarm"===e.name&&self.ServiceWorkerGlobalScope&&self instanceof ServiceWorkerGlobalScope&&(await this._isARFEnabled()?await this.cleanupEntriesOlderThanAMonth():this._clearAlarms())}async cleanupEntriesOlderThanAMonth(){await this.ready;const r=this.db.transaction(this.dbStoreName,"readwrite").objectStore(this.dbStoreName),t=Date.now()-26784e5,a=r.openCursor();return new Promise((r,s)=>{a.onsuccess=e=>{const a=e.target.result;a?(a.value?.lastSentTimeStamp<t&&a.delete(),a.continue()):r(!0)},a.onerror=r=>{e.error({message:"AnalyticsIndexedDB: Error in opening cursor to delete old entries",error:r.target.error}),s(r.target.error)}})}createAlarmForUsageMetrics(){chrome.alarms.get("analyticsInstrumentationAlarm").then(e=>{e||chrome.alarms.create("analyticsInstrumentationAlarm",{periodInMinutes:this.usageMetricsIntervalMinutes})}),chrome.alarms.onAlarm.addListener(this.usageMetricsAlarmHandler.bind(this))}async usageMetricsAlarmHandler(r){if("analyticsInstrumentationAlarm"===r.name&&self.ServiceWorkerGlobalScope&&self instanceof ServiceWorkerGlobalScope)if(await this._isARFEnabled()){const r=await this.getKeyCount();r>1e4&&e.info({message:"AnalyticsIndexedDB: Usage metrics",keyCount:r})}else this._clearAlarms()}async getKeyCount(){await this.ready;const e=this.db.transaction(this.dbStoreName,"readonly").objectStore(this.dbStoreName).getAllKeys();return new Promise((r,t)=>{e.onsuccess=e=>{r(e.target.result.length)},e.onerror=e=>{t(e.target.error)}})}openDatabase(){return new Promise((r,t)=>{const a=indexedDB.open(this.dbName,this.dbVersion);a.onupgradeneeded=e=>{this.db=e.target.result,this.db.objectStoreNames.contains(this.dbStoreName)||this.db.createObjectStore(this.dbStoreName)},a.onsuccess=e=>{this.db=e.target.result,r(this.db)},a.onerror=r=>{e.error({message:"AnalyticsIndexedDB: Error in opening database",error:r.target.error}),t(r.target.error)}})}async createTransaction(r,t){return this.ready.then(()=>new Promise((a,s)=>{const n=this.db.transaction(this.dbStoreName,"readwrite");n.onerror=r=>(e.error({message:"AnalyticsIndexedDB: Error in transaction",error:r.target.error}),Promise.reject(r.target.error));const o=n.objectStore(this.dbStoreName),i=o.get(r);i.onsuccess=n=>{const i=n.target?.result,l=t(structuredClone(i)),c=l.updatedRecord;if(JSON.stringify(i)===JSON.stringify(c))return void a(l);const d=o.put(c,r);d.onsuccess=()=>{a(l)},d.onerror=r=>{e.error({message:"AnalyticsIndexedDB: Error in updating sendState record",error:r.target.error}),s(r.target.error)}},i.onerror=r=>{e.error({message:"AnalyticsIndexedDB: Error in getting sendStaterecord",error:r.target.error}),s(r.target.error)}}))}};export{t as analyticsIndexedDB};