package ru.yandex.webmaster3.storage.recommendedquery.filtres;

import ru.yandex.webmaster3.core.WebmasterException;
import ru.yandex.webmaster3.core.http.WebmasterErrorResponse;
import ru.yandex.webmaster3.storage.AbstractFilter;
import ru.yandex.webmaster3.storage.TextFilterUtil;
import ru.yandex.webmaster3.storage.recommendedquery.RecommendedQueryInfoUtil;
import ru.yandex.webmaster3.storage.recommendedquery.dao.RecommendedQueriesCHDao;
import ru.yandex.webmaster3.storage.recommendedquery.dao.RecommendedQueriesCHDao.F;
import ru.yandex.webmaster3.storage.util.clickhouse2.condition.*;

/**
 * Created by ifilippov5 on 10.03.17.
 */
public class RecommendedQueryConditions {

    public static Condition fromFilter(AbstractFilter<RecommendedQueryField> filter) {
        try {
            Operator operator = Operator.fromFilterOperation(filter.getOperation());
            switch (filter.getIndicator()) {
                case QUERY:
                    return TextFilterUtil.getTextCondition(filter, F.QUERY.getName());
                case FORECASTED_BID:
                    return forecastedBidCondition(operator, Double.parseDouble(filter.getValue()));
                case FORECASTED_BUDGET:
                    return forecastedBudgetCondition(operator, Double.parseDouble(filter.getValue()));
                case FORECASTED_CLICKS:
                    return forecastedClicksCondition(operator, Double.parseDouble(filter.getValue()));
                case FORECASTED_SHOWS:
                    return forecastedShowsCondition(operator, Double.parseDouble(filter.getValue()));
                case URL:
                    return TextFilterUtil.getTextCondition(filter, F.URL.getName());
                case POSITION:
                    return positionCondition(operator, Integer.parseInt(filter.getValue()));
                case REGION_ID:
                    return new LongCondition(F.REGION_ID.getName(), operator, Long.parseLong(filter.getValue()));
            }
        } catch (NumberFormatException e) {
            throw new WebmasterException("Unable to parse filter value",
                    new WebmasterErrorResponse.IllegalParameterValueResponse(RecommendedQueryConditions.class, null, null), e);
        } catch (IllegalArgumentException e) {
            String message = "Bad filter: cannot apply operation " + filter.getOperation() + " to indicator " +
                    filter.getIndicator() + " and value " + filter.getValue();
            throw new WebmasterException(message,
                    new WebmasterErrorResponse.IllegalParameterValueResponse(RecommendedQueryConditions.class, null, null, message));
        }
        // should not be here
        throw new IllegalStateException();
    }

    public static Condition forecastedBidCondition(Operator op, double value) {
        return new FloatCondition(F.FORECASTED_BID.getName(), op, RecommendedQueryInfoUtil.BID_FILTER_CONVERTER.apply(value));
    }

    public static Condition forecastedBudgetCondition(Operator op, double value) {
        return new FloatCondition(F.FORECASTED_BUDGET.getName(), op, value);
    }

    public static Condition forecastedClicksCondition(Operator op, double value) {
        return new FloatCondition(F.FORECASTED_CLICKS.getName(), op, value);
    }

    public static Condition forecastedShowsCondition(Operator op, double value) {
        return new FloatCondition(F.FORECASTED_SHOWS.getName(), op, value);
    }

    public static Condition positionCondition(Operator op, int value) {
        return new LongCondition(F.POSITION.getName(), op, value);
    }
}
