text: const { asArray, isObject } = require('../utils/objectUtils');
  const { buildArg } = require('../utils/buildUtils');
  
  class LiteralBuilder {
    constructor(value) {
      this._value = value;
      this._cast = null;
      // Cast objects and arrays to json by default.
      this._toJson = isObject(value);
      this._toArray = false;
    }
  
    get cast() {
      return this._cast;
    }
  
    castText() {
      return this.castTo('text');
    }
  
    castInt() {
      return this.castTo('integer');
    }
  
    castBigInt() {
      return this.castTo('bigint');
    }
  
    castFloat() {
      return this.castTo('float');
    }
  
    castDecimal() {
      return this.castTo('decimal');
    }
  
    castReal() {
      return this.castTo('real');
    }
  
    castBool() {
      return this.castTo('boolean');
    }
  
    castJson() {
      this._toArray = false;
      this._toJson = true;
      this._cast = 'jsonb';
      return this;
    }
  
    castArray() {
      console.log(
        'castArray() is deprecated. Use asArray() instead. castArray() will be removed in 2.0'
      );
      return this.asArray();
    }
  
    castType(sqlType) {
      console.log(
        'castType(type) is deprecated. Use castTo(type) instead. castType(type) will be removed in 2.0'
      );
      return this.castTo(sqlType);
    }
  
    castTo(sqlType) {
      this._cast = sqlType;
      return this;
    }
  
    asArray() {
      this._toJson = false;
      this._toArray = true;
      return this;
    }
  
    toKnexRaw(knex) {
      let sql = null;
      let bindings = null;
  
      if (this._toJson) {
        bindings = JSON.stringify(this._value);
        sql = '?';
      } else if (this._toArray) {
        bindings = asArray(this._value).map(it => buildArg(it, knex));
        sql = `ARRAY[${bindings.map(() => '?').join(', ')}]`;
      } else {
        bindings = this._value;
        sql = '?';
      }
  
      if (this._cast) {
        sql = `CAST(${sql} AS ${this._cast})`;
      }
  
      return knex.raw(sql, bindings);
    }
  }
  
  function lit(val) {
    return new LiteralBuilder(val);
  }
  
  module.exports = {
    LiteralBuilder,
    lit
  };
  