var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.SqliteClient = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _constants = require("./constants");
var _schema = require("./schema");
var _createCreateTableQuery = require("./sqlite-utils/createCreateTableQuery");
var _SqliteClient;
var sqlite;
try {
  sqlite = require('@op-engineering/op-sqlite');
} catch (e) {
  var isRemoteDebuggerError = e instanceof Error && e.message.includes('Failed to install');
  if (isRemoteDebuggerError) {
    throw e;
  }
}
var SqliteClient = exports.SqliteClient = (0, _createClass2["default"])(function SqliteClient() {
  (0, _classCallCheck2["default"])(this, SqliteClient);
});
_SqliteClient = SqliteClient;
SqliteClient.dbVersion = 9;
SqliteClient.dbName = _constants.DB_NAME;
SqliteClient.dbLocation = _constants.DB_LOCATION;
SqliteClient.getDbVersion = function () {
  return _SqliteClient.dbVersion;
};
SqliteClient.setDbVersion = function (version) {
  return _SqliteClient.dbVersion = version;
};
SqliteClient.openDB = (0, _asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee() {
  var _SqliteClient$db;
  return _regenerator["default"].wrap(function _callee$(_context) {
    while (1) switch (_context.prev = _context.next) {
      case 0:
        _context.prev = 0;
        if (!(sqlite === undefined)) {
          _context.next = 3;
          break;
        }
        throw new Error('Please install "@op-engineering/op-sqlite" package to enable offline support');
      case 3:
        _SqliteClient.db = sqlite.open({
          location: _SqliteClient.dbLocation,
          name: _SqliteClient.dbName
        });
        _context.next = 6;
        return (_SqliteClient$db = _SqliteClient.db) == null ? void 0 : _SqliteClient$db.execute('PRAGMA foreign_keys = ON', []);
      case 6:
        _context.next = 12;
        break;
      case 8:
        _context.prev = 8;
        _context.t0 = _context["catch"](0);
        _SqliteClient.logger == null || _SqliteClient.logger('error', "Error opening database ".concat(_SqliteClient.dbName), {
          error: _context.t0
        });
        console.error("Error opening database ".concat(_SqliteClient.dbName, ": ").concat(_context.t0));
      case 12:
      case "end":
        return _context.stop();
    }
  }, _callee, null, [[0, 8]]);
}));
SqliteClient.closeDB = function () {
  try {
    if (!_SqliteClient.db) {
      throw new Error('DB is not open or initialized.');
    }
    _SqliteClient.db.close();
    _SqliteClient.db = undefined;
  } catch (e) {
    _SqliteClient.logger == null || _SqliteClient.logger('error', "Error closing database ".concat(_SqliteClient.dbName), {
      error: e
    });
    console.error("Error closing database ".concat(_SqliteClient.dbName, ": ").concat(e));
  }
};
SqliteClient.executeSqlBatch = function () {
  var _ref2 = (0, _asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee2(queries) {
    var finalQueries, _SqliteClient$db2;
    return _regenerator["default"].wrap(function _callee2$(_context2) {
      while (1) switch (_context2.prev = _context2.next) {
        case 0:
          if (!(!queries || !queries.length)) {
            _context2.next = 2;
            break;
          }
          return _context2.abrupt("return");
        case 2:
          _context2.prev = 2;
          if (_SqliteClient.db) {
            _context2.next = 5;
            break;
          }
          throw new Error('DB is not open or initialized.');
        case 5:
          finalQueries = queries.map(function (query) {
            if (query.length === 1) {
              query.push([]);
            }
            return query;
          });
          _context2.next = 8;
          return _SqliteClient.db.executeBatch(finalQueries);
        case 8:
          _context2.next = 15;
          break;
        case 10:
          _context2.prev = 10;
          _context2.t0 = _context2["catch"](2);
          (_SqliteClient$db2 = _SqliteClient.db) == null || _SqliteClient$db2.execute('ROLLBACK');
          _SqliteClient.logger == null || _SqliteClient.logger('error', 'SqlBatch queries failed', {
            error: _context2.t0,
            queries: queries
          });
          throw new Error("Queries failed: ".concat(_context2.t0));
        case 15:
        case "end":
          return _context2.stop();
      }
    }, _callee2, null, [[2, 10]]);
  }));
  return function (_x) {
    return _ref2.apply(this, arguments);
  };
}();
SqliteClient.executeSql = function () {
  var _ref3 = (0, _asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee3(query, params) {
    var _yield$_SqliteClient$, rows;
    return _regenerator["default"].wrap(function _callee3$(_context3) {
      while (1) switch (_context3.prev = _context3.next) {
        case 0:
          _context3.prev = 0;
          if (_SqliteClient.db) {
            _context3.next = 3;
            break;
          }
          throw new Error('DB is not open or initialized.');
        case 3:
          _context3.next = 5;
          return _SqliteClient.db.execute(query, params);
        case 5:
          _yield$_SqliteClient$ = _context3.sent;
          rows = _yield$_SqliteClient$.rows;
          return _context3.abrupt("return", rows ? rows : []);
        case 10:
          _context3.prev = 10;
          _context3.t0 = _context3["catch"](0);
          _SqliteClient.logger == null || _SqliteClient.logger('error', 'Sql single query failed', {
            error: _context3.t0,
            query: query
          });
          throw new Error("Query failed: ".concat(_context3.t0, ": "));
        case 14:
        case "end":
          return _context3.stop();
      }
    }, _callee3, null, [[0, 10]]);
  }));
  return function (_x2, _x3) {
    return _ref3.apply(this, arguments);
  };
}();
SqliteClient.dropTables = (0, _asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee4() {
  var queries;
  return _regenerator["default"].wrap(function _callee4$(_context4) {
    while (1) switch (_context4.prev = _context4.next) {
      case 0:
        queries = Object.keys(_schema.tables).map(function (table) {
          return ["DROP TABLE IF EXISTS ".concat(table), []];
        });
        _SqliteClient.logger == null || _SqliteClient.logger('info', 'Dropping tables', {
          tables: Object.keys(_schema.tables)
        });
        _context4.next = 4;
        return _SqliteClient.executeSqlBatch(queries);
      case 4:
      case "end":
        return _context4.stop();
    }
  }, _callee4);
}));
SqliteClient.deleteDatabase = function () {
  _SqliteClient.logger == null || _SqliteClient.logger('info', 'deleteDatabase', {
    dbLocation: _SqliteClient.dbLocation,
    dbname: _SqliteClient.dbName
  });
  try {
    if (!_SqliteClient.db) {
      throw new Error('DB is not open or initialized.');
    }
    _SqliteClient.db["delete"]();
  } catch (e) {
    _SqliteClient.logger == null || _SqliteClient.logger('error', 'Error deleting DB', {
      dbLocation: _SqliteClient.dbLocation,
      dbname: _SqliteClient.dbName,
      error: e
    });
    throw new Error("Error deleting DB: ".concat(e));
  }
  return true;
};
SqliteClient.initializeDatabase = (0, _asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee5() {
  var version, q;
  return _regenerator["default"].wrap(function _callee5$(_context5) {
    while (1) switch (_context5.prev = _context5.next) {
      case 0:
        _context5.prev = 0;
        _context5.next = 3;
        return _SqliteClient.openDB();
      case 3:
        _context5.next = 5;
        return _SqliteClient.getUserPragmaVersion();
      case 5:
        version = _context5.sent;
        if (!(version !== _SqliteClient.dbVersion)) {
          _context5.next = 12;
          break;
        }
        _SqliteClient.logger == null || _SqliteClient.logger('info', 'DB version mismatch');
        _context5.next = 10;
        return _SqliteClient.dropTables();
      case 10:
        _context5.next = 12;
        return _SqliteClient.updateUserPragmaVersion(_SqliteClient.dbVersion);
      case 12:
        _SqliteClient.logger == null || _SqliteClient.logger('info', 'create tables if not exists', {
          tables: Object.keys(_schema.tables)
        });
        q = Object.keys(_schema.tables).reduce(function (queriesSoFar, tableName) {
          queriesSoFar.push.apply(queriesSoFar, (0, _toConsumableArray2["default"])((0, _createCreateTableQuery.createCreateTableQuery)(tableName)));
          return queriesSoFar;
        }, []);
        _context5.next = 16;
        return _SqliteClient.executeSqlBatch(q);
      case 16:
        return _context5.abrupt("return", true);
      case 19:
        _context5.prev = 19;
        _context5.t0 = _context5["catch"](0);
        console.log('Error initializing DB', _context5.t0);
        _SqliteClient.logger == null || _SqliteClient.logger('error', 'Error initializing DB', {
          dbLocation: _SqliteClient.dbLocation,
          dbname: _SqliteClient.dbName,
          error: _context5.t0
        });
        return _context5.abrupt("return", false);
      case 24:
      case "end":
        return _context5.stop();
    }
  }, _callee5, null, [[0, 19]]);
}));
SqliteClient.updateUserPragmaVersion = function () {
  var _ref6 = (0, _asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee6(version) {
    return _regenerator["default"].wrap(function _callee6$(_context6) {
      while (1) switch (_context6.prev = _context6.next) {
        case 0:
          _SqliteClient.logger == null || _SqliteClient.logger('info', "updateUserPragmaVersion to ".concat(version));
          if (_SqliteClient.db) {
            _context6.next = 3;
            break;
          }
          throw new Error('DB is not open or initialized.');
        case 3:
          _context6.next = 5;
          return _SqliteClient.db.execute("PRAGMA user_version = ".concat(version), []);
        case 5:
        case "end":
          return _context6.stop();
      }
    }, _callee6);
  }));
  return function (_x4) {
    return _ref6.apply(this, arguments);
  };
}();
SqliteClient.getUserPragmaVersion = (0, _asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee7() {
  var _yield$_SqliteClient$2, rows, result;
  return _regenerator["default"].wrap(function _callee7$(_context7) {
    while (1) switch (_context7.prev = _context7.next) {
      case 0:
        _context7.prev = 0;
        if (_SqliteClient.db) {
          _context7.next = 3;
          break;
        }
        throw new Error('DB is not open or initialized.');
      case 3:
        _context7.next = 5;
        return _SqliteClient.db.execute('PRAGMA user_version', []);
      case 5:
        _yield$_SqliteClient$2 = _context7.sent;
        rows = _yield$_SqliteClient$2.rows;
        result = rows ? rows : [];
        _SqliteClient.logger == null || _SqliteClient.logger('info', 'getUserPragmaVersion', {
          result: result
        });
        return _context7.abrupt("return", result[0].user_version);
      case 12:
        _context7.prev = 12;
        _context7.t0 = _context7["catch"](0);
        console.log('Error getting user_version', _context7.t0);
        throw new Error("Querying for user_version failed: ".concat(_context7.t0));
      case 16:
      case "end":
        return _context7.stop();
    }
  }, _callee7, null, [[0, 12]]);
}));
SqliteClient.resetDB = (0, _asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee8() {
  return _regenerator["default"].wrap(function _callee8$(_context8) {
    while (1) switch (_context8.prev = _context8.next) {
      case 0:
        _SqliteClient.logger == null || _SqliteClient.logger('info', 'resetDB');
        if (!_SqliteClient.db) {
          _context8.next = 5;
          break;
        }
        _context8.next = 4;
        return _SqliteClient.dropTables();
      case 4:
        _SqliteClient.closeDB();
      case 5:
        _context8.next = 7;
        return _SqliteClient.initializeDatabase();
      case 7:
      case "end":
        return _context8.stop();
    }
  }, _callee8);
}));
//# sourceMappingURL=SqliteClient.js.map