"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.ENCRYPTION_OFF = exports.ENCRYPTION_ON = exports.validateStatementAndParameters = exports.assertValidDate = exports.assertNumberOrInteger = exports.assertNumber = exports.assertString = exports.assertObject = exports.isString = exports.isObject = exports.isEmptyObjectOrNull = undefined;

var _isNan = require("babel-runtime/core-js/number/is-nan");

var _isNan2 = _interopRequireDefault(_isNan);

var _stringify = require("babel-runtime/core-js/json/stringify");

var _stringify2 = _interopRequireDefault(_stringify);

var _typeof2 = require("babel-runtime/helpers/typeof");

var _typeof3 = _interopRequireDefault(_typeof2);

var _integer = require("../integer");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var ENCRYPTION_ON = "ENCRYPTION_ON"; /**
                                      * Copyright (c) 2002-2018 "Neo4j,"
                                      * Neo4j Sweden AB [http://neo4j.com]
                                      *
                                      * This file is part of Neo4j.
                                      *
                                      * Licensed under the Apache License, Version 2.0 (the "License");
                                      * you may not use this file except in compliance with the License.
                                      * You may obtain a copy of the License at
                                      *
                                      *     http://www.apache.org/licenses/LICENSE-2.0
                                      *
                                      * Unless required by applicable law or agreed to in writing, software
                                      * distributed under the License is distributed on an "AS IS" BASIS,
                                      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                                      * See the License for the specific language governing permissions and
                                      * limitations under the License.
                                      */

var ENCRYPTION_OFF = "ENCRYPTION_OFF";

function isEmptyObjectOrNull(obj) {
  if (obj === null) {
    return true;
  }

  if (!isObject(obj)) {
    return false;
  }

  for (var prop in obj) {
    if (obj.hasOwnProperty(prop)) {
      return false;
    }
  }

  return true;
}

function isObject(obj) {
  return (typeof obj === "undefined" ? "undefined" : (0, _typeof3.default)(obj)) === 'object' && !Array.isArray(obj) && obj !== null;
}

/**
 * Check and normalize given statement and parameters.
 * @param {string|{text: string, parameters: object}} statement the statement to check.
 * @param {object} parameters
 * @return {{query: string, params: object}} the normalized query with parameters.
 * @throws TypeError when either given query or parameters are invalid.
 */
function validateStatementAndParameters(statement, parameters) {
  var query = statement;
  var params = parameters || {};

  if ((typeof statement === "undefined" ? "undefined" : (0, _typeof3.default)(statement)) === 'object' && statement.text) {
    query = statement.text;
    params = statement.parameters || {};
  }

  assertCypherStatement(query);
  assertQueryParameters(params);

  return { query: query, params: params };
}

function assertObject(obj, objName) {
  if (!isObject(obj)) {
    throw new TypeError(objName + ' expected to be an object but was: ' + (0, _stringify2.default)(obj));
  }
  return obj;
}

function assertString(obj, objName) {
  if (!isString(obj)) {
    throw new TypeError(objName + ' expected to be string but was: ' + (0, _stringify2.default)(obj));
  }
  return obj;
}

function assertNumber(obj, objName) {
  if (typeof obj !== 'number') {
    throw new TypeError(objName + ' expected to be a number but was: ' + (0, _stringify2.default)(obj));
  }
  return obj;
}

function assertNumberOrInteger(obj, objName) {
  if (typeof obj !== 'number' && !(0, _integer.isInt)(obj)) {
    throw new TypeError(objName + ' expected to be either a number or an Integer object but was: ' + (0, _stringify2.default)(obj));
  }
  return obj;
}

function assertValidDate(obj, objName) {
  if (Object.prototype.toString.call(obj) !== '[object Date]') {
    throw new TypeError(objName + ' expected to be a standard JavaScript Date but was: ' + (0, _stringify2.default)(obj));
  }
  if ((0, _isNan2.default)(obj.getTime())) {
    throw new TypeError(objName + ' expected to be valid JavaScript Date but its time was NaN: ' + (0, _stringify2.default)(obj));
  }
  return obj;
}

function assertCypherStatement(obj) {
  assertString(obj, 'Cypher statement');
  if (obj.trim().length === 0) {
    throw new TypeError('Cypher statement is expected to be a non-empty string.');
  }
}

function assertQueryParameters(obj) {
  if (!isObject(obj)) {
    // objects created with `Object.create(null)` do not have a constructor property
    var _constructor = obj.constructor ? ' ' + obj.constructor.name : '';
    throw new TypeError("Query parameters are expected to either be undefined/null or an object, given:" + _constructor + " " + obj);
  }
}

function isString(str) {
  return Object.prototype.toString.call(str) === '[object String]';
}

exports.isEmptyObjectOrNull = isEmptyObjectOrNull;
exports.isObject = isObject;
exports.isString = isString;
exports.assertObject = assertObject;
exports.assertString = assertString;
exports.assertNumber = assertNumber;
exports.assertNumberOrInteger = assertNumberOrInteger;
exports.assertValidDate = assertValidDate;
exports.validateStatementAndParameters = validateStatementAndParameters;
exports.ENCRYPTION_ON = ENCRYPTION_ON;
exports.ENCRYPTION_OFF = ENCRYPTION_OFF;