/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.unomi.plugins.baseplugin.conditions;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.unomi.api.conditions.Condition;
import org.apache.unomi.persistence.elasticsearch.conditions.ConditionContextHelper;
import org.apache.unomi.persistence.elasticsearch.conditions.ConditionESQueryBuilder;
import org.apache.unomi.persistence.elasticsearch.conditions.ConditionESQueryBuilderDispatcher;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class PropertyConditionESQueryBuilder implements ConditionESQueryBuilder {

    DateTimeFormatter dateTimeFormatter;

    public PropertyConditionESQueryBuilder() {
        dateTimeFormatter = ISODateTimeFormat.dateTime();
    }

    @Override
    public QueryBuilder buildQuery(Condition condition, Map<String, Object> context, ConditionESQueryBuilderDispatcher dispatcher) {
        String comparisonOperator = (String) condition.getParameter("comparisonOperator");
        String name = (String) condition.getParameter("propertyName");

        if (comparisonOperator == null || name == null) {
            throw new IllegalArgumentException("Impossible to build ES filter, condition is not valid, comparisonOperator and propertyName properties should be provided");
        }

        String expectedValue = ConditionContextHelper.foldToASCII((String) condition.getParameter("propertyValue"));
        Object expectedValueInteger = condition.getParameter("propertyValueInteger");
        Object expectedValueDate = convertDateToISO(condition.getParameter("propertyValueDate"));
        Object expectedValueDateExpr = condition.getParameter("propertyValueDateExpr");

        List<?> expectedValues = ConditionContextHelper.foldToASCII((List<?>) condition.getParameter("propertyValues"));
        List<?> expectedValuesInteger = (List<?>) condition.getParameter("propertyValuesInteger");
        List<?> expectedValuesDate = convertDatesToISO((List<?>) condition.getParameter("propertyValuesDate"));
        List<?> expectedValuesDateExpr = (List<?>) condition.getParameter("propertyValuesDateExpr");

        Object value = ObjectUtils.firstNonNull(expectedValue, expectedValueInteger, expectedValueDate, expectedValueDateExpr);
        @SuppressWarnings("unchecked")
        List<?> values = ObjectUtils.firstNonNull(expectedValues, expectedValuesInteger, expectedValuesDate, expectedValuesDateExpr);

        switch (comparisonOperator) {
            case "equals":
                checkRequiredValue(value, name, comparisonOperator, false);
                return QueryBuilders.termQuery(name, value);
            case "notEquals":
                checkRequiredValue(value, name, comparisonOperator, false);
                return QueryBuilders.boolQuery().mustNot(QueryBuilders.termQuery(name, value));
            case "greaterThan":
                checkRequiredValue(value, name, comparisonOperator, false);
                return QueryBuilders.rangeQuery(name).gt(value);
            case "greaterThanOrEqualTo":
                checkRequiredValue(value, name, comparisonOperator, false);
                return QueryBuilders.rangeQuery(name).gte(value);
            case "lessThan":
                checkRequiredValue(value, name, comparisonOperator, false);
                return QueryBuilders.rangeQuery(name).lt(value);
            case "lessThanOrEqualTo":
                checkRequiredValue(value, name, comparisonOperator, false);
                return QueryBuilders.rangeQuery(name).lte(value);
            case "between":
                checkRequiredValuesSize(values, name, comparisonOperator, 2);
                return QueryBuilders.rangeQuery(name).gte(values.get(0)).lte(values.get(1));
            case "exists":
                return QueryBuilders.existsQuery(name);
            case "missing":
                return QueryBuilders.boolQuery().mustNot(QueryBuilders.existsQuery((name)));
            case "contains":
                checkRequiredValue(expectedValue, name, comparisonOperator, false);
                return QueryBuilders.regexpQuery(name, ".*" + expectedValue + ".*");
            case "notContains":
                checkRequiredValue(expectedValue, name, comparisonOperator, false);
                return QueryBuilders.boolQuery().mustNot(QueryBuilders.regexpQuery(name, ".*" + expectedValue + ".*"));
            case "startsWith":
                checkRequiredValue(expectedValue, name, comparisonOperator, false);
                return QueryBuilders.prefixQuery(name, expectedValue);
            case "endsWith":
                checkRequiredValue(expectedValue, name, comparisonOperator, false);
                return QueryBuilders.regexpQuery(name, ".*" + expectedValue);
            case "matchesRegex":
                checkRequiredValue(expectedValue, name, comparisonOperator, false);
                return QueryBuilders.regexpQuery(name, expectedValue);
            case "in":
                checkRequiredValue(values, name, comparisonOperator, true);
                return QueryBuilders.termsQuery(name, values.toArray());
            case "notIn":
                checkRequiredValue(values, name, comparisonOperator, true);
                return QueryBuilders.boolQuery().mustNot(QueryBuilders.termsQuery(name, values.toArray()));
            case "all":
                checkRequiredValue(values, name, comparisonOperator, true);
                BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
                for (Object curValue : values) {
                    boolQueryBuilder.must(QueryBuilders.termQuery(name, curValue));
                }
                return boolQueryBuilder;
            case "inContains":
                checkRequiredValue(values, name, comparisonOperator, true);
                BoolQueryBuilder boolQueryBuilderInContains = QueryBuilders.boolQuery();
                for (Object curValue : values) {
                    boolQueryBuilderInContains.must(QueryBuilders.regexpQuery(name, ".*" + curValue + ".*"));
                }
                return boolQueryBuilderInContains;
            case "hasSomeOf":
                checkRequiredValue(values, name, comparisonOperator, true);
                boolQueryBuilder = QueryBuilders.boolQuery();
                for (Object curValue : values) {
                    boolQueryBuilder.should(QueryBuilders.termQuery(name, curValue));
                }
                return boolQueryBuilder;
            case "hasNoneOf":
                checkRequiredValue(values, name, comparisonOperator, true);
                boolQueryBuilder = QueryBuilders.boolQuery();
                for (Object curValue : values) {
                    boolQueryBuilder.mustNot(QueryBuilders.termQuery(name, curValue));
                }
                return boolQueryBuilder;
            case "isDay":
                checkRequiredValue(value, name, comparisonOperator, false);
                return getIsSameDayRange(value, name);
            case "isNotDay":
                checkRequiredValue(value, name, comparisonOperator, false);
                return QueryBuilders.boolQuery().mustNot(getIsSameDayRange(value, name));
        }
        return null;
    }

    private void checkRequiredValuesSize(List<?> values, String name, String operator, int expectedSize) {
        if (values == null || values.size() != expectedSize) {
            throw new IllegalArgumentException("Impossible to build ES filter, missing " + expectedSize + " values for a condition using comparisonOperator: " + operator + ", and propertyName: " + name);
        }
    }

    private void checkRequiredValue(Object value, String name, String operator, boolean multiple) {
        if (value == null) {
            throw new IllegalArgumentException("Impossible to build ES filter, missing value" + (multiple ? "s" : "") + " for condition using comparisonOperator: " + operator + ", and propertyName: " + name);
        }
    }

    private QueryBuilder getIsSameDayRange(Object value, String name) {
        DateTime date = new DateTime(value);
        DateTime dayStart = date.withTimeAtStartOfDay();
        DateTime dayAfterStart = date.plusDays(1).withTimeAtStartOfDay();
        return QueryBuilders.rangeQuery(name).gte(convertDateToISO(dayStart.toDate())).lte(convertDateToISO(dayAfterStart.toDate()));
    }

    private Object convertDateToISO(Object dateValue) {
        if (dateValue == null) {
            return dateValue;
        }
        if (dateValue instanceof Date) {
            return dateTimeFormatter.print(new DateTime(dateValue));
        } else {
            return dateValue;
        }
    }

    private List<?> convertDatesToISO(List<?> datesValues) {
        List<Object> results = new ArrayList<>();
        if (datesValues == null) {
            return null;
        }
        for (Object dateValue : datesValues) {
            if (dateValue != null) {
                results.add(convertDateToISO(dateValue));
            }
        }
        return results;
    }
}
