package ru.yandex.webmaster3.viewer.http.util;

import com.google.re2j.PatternSyntaxException;
import ru.yandex.autodoc.common.doc.annotation.Description;
import ru.yandex.webmaster3.core.WebmasterException;
import ru.yandex.webmaster3.core.http.*;
import ru.yandex.webmaster3.core.metrics.Category;
import ru.yandex.webmaster3.storage.TextFilterUtil;
import ru.yandex.webmaster3.storage.util.clickhouse2.condition.ConditionFieldExtractor;
import ru.yandex.webmaster3.viewer.http.util.ValidateFilterRegexAction.Request;
import ru.yandex.webmaster3.viewer.http.util.ValidateFilterRegexAction.Response;

import java.util.ArrayList;
import java.util.List;

/**
 * Валидирует значение фильтра
 * Created by Oleg Bazdyrev on 05/05/2017.
 */
@ReadAction
@Category("validation")
@Description("Валидирует значение многострочного фильтра с оператором TEXT_MATCH")
public class ValidateFilterRegexAction extends Action<Request, Response> {

    @Override
    public Response process(Request request) throws WebmasterException {
        // парсим построчно фильтры и ругаемся, если что-то не так
        boolean valid = true;
        List<FilterLine> filterLines = new ArrayList<>();
        for (String line : request.getQuery().split(TextFilterUtil.DELIMITER_OF_DIFFERENT_FILTERS)) {
            try {
                TextFilterUtil.parseCondition(null, line).toPredicate(ConditionFieldExtractor.identity(String.class));
                filterLines.add(new FilterLine(line, true));
            } catch (PatternSyntaxException e) {
                valid = false;
                filterLines.add(new FilterLine(line, false));
            }
        }
        return new Response(valid, filterLines);
    }

    public static class Request implements ActionRequest {
        private String query;

        public String getQuery() {
            return query;
        }

        @RequestQueryProperty(required = true)
        @Description("Значение фильтра, которое требуется валидировать")
        public void setQuery(String query) {
            this.query = query;
        }
    }

    public static class Response implements ActionResponse {

        private final boolean valid;
        private final List<FilterLine> filterLines;

        public Response(boolean valid, List<FilterLine> filterLines) {
            this.valid = valid;
            this.filterLines = filterLines;
        }

        @Override
        public ActionStatus getRequestStatus() {
            return ActionStatus.SUCCESS;
        }

        @Description("Валиден ли текст фильтра")
        public boolean isValid() {
            return valid;
        }

        @Description("Отдельные строки фильтра")
        public List<FilterLine> getFilterLines() {
            return filterLines;
        }
    }

    public static class FilterLine {

        private final String expression;
        private final boolean valid;

        public FilterLine(String expression, boolean valid) {
            this.expression = expression;
            this.valid = valid;
        }

        @Description("Текст фильтра строки")
        public String getExpression() {
            return expression;
        }

        @Description("Валиден ли текст фильтра строки")
        public boolean isValid() {
            return valid;
        }
    }

}
