package io.delphiplatform.api.v3.rdb.service.specification;

import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;

import io.delphiplatform.api.util.JpaUtils;

public class SingleValuePropertyLikeIgnoreCaseSpecification<T> extends OperationOnPropertySpecification<T> {

    private final List<String> propertyPath;
    private final String searchValue;

    public SingleValuePropertyLikeIgnoreCaseSpecification(List<String> propertyPath, String searchValue, List<String> joins,
        boolean doDistinct) {
        super(joins, doDistinct);
        this.propertyPath = propertyPath;
        this.searchValue = searchValue;
    }

    @Override
    protected boolean canProducePredicate() {
        return searchValue != null;
    }

    @Override
    protected Predicate doOperation(CriteriaBuilder cb, Path<T> path) {
        @SuppressWarnings("unchecked")
        Expression<String> pathToTextField = (Expression<String>) JpaUtils.getPath(path, propertyPath);

        if (!pathToTextField.getJavaType().equals(String.class)) {
            throw new IllegalArgumentException(String.format("This specification is only for text fields. "
                + "Property path must point to text field, not '%s'", pathToTextField.getJavaType()));
        }

        return cb.like(cb.upper(pathToTextField), "%" + searchValue.toUpperCase() + "%");
    }
}
