fcf.module({
  name: "fcf:NFSQL/NFilter/Datetime.js",
  dependencies: ["fcf:NFSQL/NFilter/BaseSimpleType.js", "fcf:NFSQL/NFilter/Errors.js"],
  module: function(BaseSimpleType, Errors){
    var Namespace = fcf.prepareObject(fcf, "packages/fcf/NFSQL/NFilter");

    class Datetime extends BaseSimpleType{
      constructor() {
        super({type: "boolean"});
        this.comparisons = {
          "*": ["=", "<>", "<", "<=", ">", ">="],
        };
      }

      validate(a_description, a_dstErrors) {
        var value = a_description.data;
        var field = a_description.field;

        if ((a_description.field.notEmpty || a_description.field.notNull) && fcf.empty(value) ) {
          a_dstErrors.push(new fcf.Exception("ERROR_FIELD_VALIDATION_NOT_EMPTY"));
          return;
        }

        if (fcf.empty(value))
          return;

        if (isNaN((new Date(value)).getTime()))
          a_dstErrors.push(new fcf.Exception("ERROR_NFSQL_INCORRECT_DATETIME_TYPE", {projection: a_description.selfProjection, field: field.alias, value: value}));
      }

      postProcessOutputField(a_taskInfo, a_info){
        for(let i = 0; i < a_taskInfo.result.length; ++i){
          if (a_taskInfo.result[i][a_info.field.as]){
            let date    = new Date(a_taskInfo.result[i][a_info.field.as])
            let rawDate = !isNaN(date.getTime()) ? date.toISOString() : null;
            a_taskInfo.result[i][a_info.field.as] = rawDate;
          }
        }
      }

      processUpdateField(a_taskInfo, a_info){
        super.processUpdateField(a_taskInfo, a_info);
        let date = new Date(a_info.field.value);
        a_info.field.value = !isNaN(date.getTime()) ? fcf.dateFormat(date, "Y-m-d H:i:s.u", false) : null;
      }

      processInsertField(a_taskInfo, a_info){
        super.processInsertField(a_taskInfo, a_info);
        let date = new Date(a_info.field.value);
        a_info.field.value = !isNaN(date.getTime()) ? fcf.dateFormat(date, "Y-m-d H:i:s.u", false) : null;
      }


    };

    Namespace.Datetime = Datetime;

    return Namespace.Datetime;
  }
});
