/**
 * vue-cesium - https://github.com/zouyaoji/vue-cesium
 * Vue 2.x components for CesiumJS.
 *
 * @package VueCesium
 * @author zouyaoji <370681295@qq.com>
 * @version 2.3.12
 * @license MIT
 * @homepage https://zouyaoji.top/vue-cesium
 * @copyright (c) 2018-2022, zouyaoji <370681295@qq.com>
 */
import _classCallCheck from '@babel/runtime-corejs2/helpers/esm/classCallCheck';
import _createClass from '@babel/runtime-corejs2/helpers/esm/createClass';
import _Promise from '@babel/runtime-corejs2/core-js/promise';
import _parseInt from '@babel/runtime-corejs2/core-js/parse-int';

/* eslint-disable prefer-promise-reject-errors */

/**
 * 操作状态。
 */
var Status = {
  NONE: 0,
  STORING: 1,
  STORED: 2,
  FAILED: 3
};
/**
 * 操作浏览器数据库 IndexedDB 类
 */

var IndexedDBScheduler = /*#__PURE__*/function () {
  /**
   *
   * @param {Object} options
   */
  function IndexedDBScheduler(options) {
    _classCallCheck(this, IndexedDBScheduler);

    if (!Cesium.defined(options.name)) {
      throw new Cesium.DeveloperError('options.name is required.');
    }

    var dbRequest = window.indexedDB.open(this.dbname);
    this.layer = options.layer || null;
    this.storageType = options.storageType || 'arrayBuffer';
    this.creatingTable = !1;
    this.cachestatus = {};
    this.dbname = options.name;
    var that = this;
    return new _Promise(function (resolve, reject) {
      dbRequest.onsuccess = function (event) {
        that.db = event.target.result;
        that.version = that.db.version;
        that.cachestatus = that.cachestatus || {};
        resolve(that);
      };

      dbRequest.onupgradeneeded = function (event) {
        that.db = event.target.result;
        that.version = that.db.version;
        resolve(that);
      };

      dbRequest.onerror = function (event) {
        that.db = null;
        reject('create database fail, error code : ' + event.target.errorcode);
      };
    });
  }
  /**
   * 检查对象仓库是否存在。
   * @param {String} storeName 对象仓库（表）名称
   */


  _createClass(IndexedDBScheduler, [{
    key: "checkObjectStoreExist",
    value: function checkObjectStoreExist(storeName) {
      return Cesium.defined(this.db) ? this.db.objectStoreNames.contains(storeName) : false;
    }
    /**
     *  创建 IndexedDB 浏对象仓库，IndexedDB 是浏览器提供的本地数据库
     * @param {String} storeName 对象仓库（表）名称
     * @returns {Promise}
     */

  }, {
    key: "createObjectStore",
    value: function createObjectStore(storeName) {
      var _this = this;

      return new _Promise(function (resolve, reject) {
        if (_this.creatingTable) {
          reject(false);
        } else {
          if (_this.db.objectStoreNames.contains(storeName)) {
            reject(false);
            return;
          }

          _this.creatingTable = true;

          var version = _parseInt(_this.db.version);

          _this.db.close();

          var that = _this; // 打开或新建 IndexedDB 数据库

          var dbRequest = window.indexedDB.open(_this.dbname, version + 1);

          dbRequest.onupgradeneeded = function (event) {
            var db = event.target.result;
            that.db = db; // 创建对象仓库（表）

            var objectStore = db.createObjectStore(storeName, {
              keyPath: 'id'
            });

            if (Cesium.defined(objectStore)) {
              // 创建索引
              objectStore.createIndex('value', 'value', {
                unique: false
              });
              that.creatingTable = false;
              that.cachestatus = that.cachestatus || {};
              that.cachestatus[storeName] = {};
              that.db.close();

              var _dbRequest = window.indexedDB.open(that.dbname);

              _dbRequest.onsuccess = function (event) {
                that.db = event.target.result;
                resolve(true);
              };
            } else {
              that.creatingTable = false;
              resolve(false);
            }
          };

          dbRequest.onsuccess = function (event) {
            event.target.result.close();
            resolve(true);
          };

          dbRequest.onerror = function (event) {
            that.creatingTable = false;
            reject(false);
          };
        }
      });
    }
    /**
     * 向对象仓库写入数据记录。
     * @param {String} storeName 对象仓库（表）名称
     * @param {Number} id 主键
     * @param {*} value 值
     * @returns {Promise}
     */

  }, {
    key: "putElementInDB",
    value: function putElementInDB(storeName, id, value) {
      var _this2 = this;

      return new _Promise(function (resolve, reject) {
        if (!Cesium.defined(_this2.db)) {
          reject(false);
          return;
        }

        var cachestatus = _this2.cachestatus,
            db = _this2.db;

        if (Cesium.defined(cachestatus[storeName]) && Cesium.defined(cachestatus[storeName][id] && (cachestatus[storeName][id] === Status.STORING || cachestatus[storeName][id] === Status.STORED))) {
          resolve(false);
          return;
        }

        if (db.objectStoreNames.contains(storeName)) {
          cachestatus[storeName] = cachestatus[storeName] || {};

          try {
            var request = db.transaction([storeName], 'readwrite').objectStore(storeName).add({
              id: id,
              value: value
            });
            cachestatus[storeName][id] = Status.STORING;

            request.onsuccess = function (event) {
              cachestatus[storeName][id] = Status.STORED;
              resolve(true);
            };

            request.onerror = function (event) {
              cachestatus[storeName][id] = Status.FAILED;
              resolve(false);
            };
          } catch (error) {
            reject(null);
          }
        } else {
          _this2.createObjectStore(storeName).then(function () {
            var request = db.transaction([storeName], 'readwrite').objectStore(storeName).add({
              id: id,
              value: value
            });

            request.onsuccess = function (e) {
              resolve(true);
            };

            request.onerror = function (e) {
              reject(false);
            };
          }, function () {
            reject(false);
          });
        }
      });
    }
    /**
     * 向对象仓库读取数据。
     * @param {String} storeName 对象仓库（表）名称
     * @param {Number} id 主键
     * @returns {Promise}
     */

  }, {
    key: "getElementFromDB",
    value: function getElementFromDB(storeName, id) {
      var _this3 = this;

      return new _Promise(function (resolve, reject) {
        var db = _this3.db;

        if (!Cesium.defined(db)) {
          return null;
        }

        if (!db.objectStoreNames.contains(storeName)) {
          return null;
        }

        try {
          var transaction = db.transaction([storeName]);
          var objectStore = transaction.objectStore(storeName);
          var request = objectStore.get(id);

          request.onsuccess = function (e) {
            return Cesium.defined(e.target.result) ? resolve(e.target.result.value) : reject(null);
          };

          request.onerror = function (e) {
            reject(null);
          };
        } catch (error) {
          reject(null);
        }
      });
    }
    /**
     * 更新数据。
     * @param {String} storeName
     * @param {Number} id
     * @param {*} value
     * @returns {Promise}
     */

  }, {
    key: "updateElementInDB",
    value: function updateElementInDB(storeName, id, value) {
      var _this4 = this;

      return new _Promise(function (resolve, reject) {
        var db = _this4.db;

        if (!Cesium.defined(db)) {
          resolve(false);
          return;
        }

        if (!db.objectStoreNames.contains(storeName)) {
          resolve(false);
          return;
        }

        try {
          var request = db.transaction([storeName], 'readwrite').objectStore(storeName).put({
            id: id,
            value: value
          });

          request.onsuccess = function () {
            resolve(true);
          };

          request.onerror = function () {
            resolve(false);
          };
        } catch (e) {
          resolve(false);
        }
      });
    }
    /**
     * 移除数据。
     * @param {String} storeName
     * @param {Number} id
     * @returns {Promise}
     */

  }, {
    key: "removeElementFromDB",
    value: function removeElementFromDB(storeName, id) {
      var _this5 = this;

      return new _Promise(function (resolve, reject) {
        var db = _this5.db;

        if (!Cesium.defined(db)) {
          resolve(false);
          return;
        }

        if (!db.objectStoreNames.contains(storeName)) {
          resolve(false);
          return;
        }

        try {
          var request = db.transaction([storeName], 'readwrite').objectStore(storeName).delete(id);

          request.onsuccess = function () {
            resolve(true);
          };

          request.onerror = function () {
            resolve(false);
          };
        } catch (e) {
          resolve(false);
        }
      });
    }
    /**
     *  清空对象仓库
     * @param {String} storeName
     */

  }, {
    key: "clear",
    value: function clear(storeName) {
      var _this6 = this;

      return new _Promise(function (resolve, reject) {
        var db = _this6.db;

        if (!Cesium.defined(db)) {
          resolve(false);
          return;
        }

        if (!db.objectStoreNames.contains(storeName)) {
          resolve(false);
          return;
        }

        try {
          var request = db.transaction([storeName], 'readwrite').objectStore(storeName).clear();

          request.onsuccess = function () {
            resolve(true);
          };

          request.onerror = function () {
            resolve(false);
          };
        } catch (e) {
          resolve(false);
        }
      });
    }
  }]);

  return IndexedDBScheduler;
}();

export default IndexedDBScheduler;
