package io.vertx.ext.web.validation.impl.validator;

import io.vertx.core.Future;
import io.vertx.ext.web.validation.RequestParameter;
import io.vertx.json.schema.NoSyncValidationException;
import io.vertx.json.schema.Schema;
import io.vertx.json.schema.ValidationException;
import io.vertx.json.schema.common.SchemaImpl;

public class SchemaValidator implements ValueValidator {

  Schema s;

  public SchemaValidator(Schema s) {
    this.s = s;
  }

  @Override
  public Future<RequestParameter> validate(Object json) {
    if (s.isSync()) {
      try {
        s.validateSync(json);
        ((SchemaImpl) s).getOrApplyDefaultSync(json);
        return Future.succeededFuture(RequestParameter.create(json));
      } catch (ValidationException e) {
        return Future.failedFuture(e);
      }
    }
    return s.validateAsync(json).map(v -> {
      try {
        ((SchemaImpl) s).getOrApplyDefaultAsync(json);
      } catch (NoSyncValidationException e) {
        // This happens if I try to apply default values to an async ref schema
      }
      return RequestParameter.create(json);
    });
  }

  @Override
  public Future<Object> getDefault() {
    if (s.isSync()) {
      return Future.succeededFuture( ((SchemaImpl) s).getOrApplyDefaultSync(null));
    }
    return ((SchemaImpl) s).getOrApplyDefaultAsync(null);
  }
}
