/*
 * 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.
 */

#include "expression.h"

#include "reader/filter/and_filter.h"
#include "reader/filter/or_filter.h"

namespace storage {

void QueryExpression::add_time_filter_to_series_filter(
    Filter* time_filter, Expression* single_series_expr) {
    Filter* filter = new AndFilter(single_series_expr->filter_, time_filter);
    single_series_expr->filter_ = filter;
    my_filters_.push_back(filter);
}

void QueryExpression::add_time_filter_to_query_filter(Filter* time_filter,
                                                      Expression* expression) {
    if (expression->type_ == SERIES_EXPR) {
        add_time_filter_to_series_filter(time_filter, expression);
    } else if ((expression->type_ == AND_EXPR) ||
               (expression->type_ == OR_EXPR)) {
        add_time_filter_to_query_filter(time_filter, expression->left_);
        add_time_filter_to_query_filter(time_filter, expression->right_);
    } else {
        std::cout << "Expression should contains only SingleSeriesExpression "
                     "but other type is found"
                  << std::endl;
    }
}

Expression* QueryExpression::combine_two_global_time_filter(
    Expression* left, Expression* right, ExpressionType type) {
    if (type == AND_EXPR) {
        Filter* filter = new AndFilter(left->filter_, right->filter_);
        Expression* expr = new Expression(GLOBALTIME_EXPR, filter);
        my_filters_.push_back(filter);
        my_exprs_.push_back(expr);
        return expr;
    } else if (type == OR_EXPR) {
        Filter* filter = new OrFilter(left->filter_, right->filter_);
        Expression* expr = new Expression(GLOBALTIME_EXPR, filter);
        my_filters_.push_back(filter);
        my_exprs_.push_back(expr);
        return expr;
    }
    std::cout << "unrecognized QueryFilterOperatorType :" << type << std::endl;
    return nullptr;
}

bool QueryExpression::update_filter_with_or(Expression* expression,
                                            Filter* filter, Path& path) {
    if (expression->type_ == SERIES_EXPR && expression->series_path_ == path) {
        Filter* node_filter = expression->filter_;
        node_filter = new OrFilter(node_filter, filter);
        my_filters_.push_back(node_filter);
        expression->filter_ = node_filter;
        return true;
    } else if (expression->type_ == OR_EXPR) {
        Expression* left = expression->left_;
        Expression* right = expression->right_;
        return update_filter_with_or(left, filter, path) ||
               update_filter_with_or(right, filter, path);
    } else {
        return false;
    }
}

Expression* QueryExpression::merge_second_tree_to_first_tree(
    Expression* left_expression, Expression* right_expression) {
    if (right_expression->type_ == SERIES_EXPR) {
        Expression* leaf = right_expression;
        update_filter_with_or(left_expression, leaf->filter_,
                              leaf->series_path_);
        return left_expression;
    } else if (right_expression->type_ == OR_EXPR) {
        Expression* left_child = right_expression->left_;
        Expression* right_child = right_expression->right_;
        left_expression =
            merge_second_tree_to_first_tree(left_expression, left_child);
        left_expression =
            merge_second_tree_to_first_tree(left_expression, right_child);
        return left_expression;
    } else {
        Expression* expr =
            new Expression(OR_EXPR, left_expression, right_expression);
        my_exprs_.push_back(expr);
        return expr;
    }
}

Expression* QueryExpression::push_global_time_filter_to_all_series(
    Expression* time_filter, std::vector<Path>& selected_series) {
    if (selected_series.empty()) {
        std::cout << "size of selectSeries could not be 0" << std::endl;
        return nullptr;
    }

    Expression* expression = new Expression(SERIES_EXPR, selected_series.at(0),
                                            time_filter->filter_);
    my_exprs_.push_back(expression);
    for (uint32_t i = 1; i < selected_series.size(); i++) {
        Expression* r = new Expression(SERIES_EXPR, selected_series.at(i),
                                       time_filter->filter_);
        expression = new Expression(OR_EXPR, expression, r);
        my_exprs_.push_back(r);
        my_exprs_.push_back(expression);
    }
    return expression;
}

Expression* QueryExpression::handle_one_global_time_filter(
    Expression* left, Expression* expression,
    std::vector<Path>& selected_series, ExpressionType type) {
    Expression* expr = optimize(expression, selected_series);
    if (expr == nullptr) {
        return nullptr;
    }

    if (expr->type_ == GLOBALTIME_EXPR) {
        return combine_two_global_time_filter(left, expr, type);
    }

    if (type == AND_EXPR) {
        add_time_filter_to_query_filter(left->filter_, expr);
        return expr;
    } else if (type == OR_EXPR) {
        Expression* after_transform =
            push_global_time_filter_to_all_series(left, selected_series);
        if (after_transform == nullptr) {
            return nullptr;
        }
        return merge_second_tree_to_first_tree(after_transform, expr);
    }
    std::cout << "unknown relation in Expression:" << type << std::endl;
    return nullptr;
}

Expression* QueryExpression::optimize(Expression* expression,
                                      std::vector<Path>& series_paths) {
    ExpressionType type = expression->type_;
    if (type == GLOBALTIME_EXPR || type == SERIES_EXPR) {
        return expression;
    } else if (type == AND_EXPR || type == OR_EXPR) {
        Expression* left = expression->left_;
        Expression* right = expression->right_;
        if (left->type_ == GLOBALTIME_EXPR && right->type_ == GLOBALTIME_EXPR) {
            return combine_two_global_time_filter(left, right, type);
        } else if (left->type_ == GLOBALTIME_EXPR &&
                   right->type_ != GLOBALTIME_EXPR) {
            return handle_one_global_time_filter(left, right, series_paths,
                                                 type);
        } else if (left->type_ != GLOBALTIME_EXPR &&
                   right->type_ == GLOBALTIME_EXPR) {
            return handle_one_global_time_filter(right, left, series_paths,
                                                 type);
        } else if (left->type_ != GLOBALTIME_EXPR &&
                   right->type_ != GLOBALTIME_EXPR) {
            Expression* regular_left = optimize(left, series_paths);
            Expression* regular_right = optimize(right, series_paths);
            if (regular_left == nullptr || regular_right == nullptr) {
                return nullptr;
            }
            Expression* mid_ret = nullptr;
            if (type == AND_EXPR) {
                mid_ret = new Expression(AND_EXPR, regular_left, regular_right);
                my_exprs_.push_back(mid_ret);
            } else if (type == OR_EXPR) {
                mid_ret = new Expression(OR_EXPR, regular_left, regular_right);
                my_exprs_.push_back(mid_ret);
            } else {
                std::cout << "unsupported Expression type:" << type
                          << std::endl;
            }

            if (mid_ret->left_->type_ == GLOBALTIME_EXPR ||
                mid_ret->right_->type_ == GLOBALTIME_EXPR) {
                return optimize(mid_ret, series_paths);
            } else {
                return mid_ret;
            }
        }
    } else {
        std::cout << "unknown Expression type:" << type << std::endl;
    }
    return nullptr;
}

void QueryExpression::destory() {
    for (size_t i = 0; i < my_exprs_.size(); i++) {
        delete my_exprs_[i];
        my_exprs_[i] = nullptr;
    }
    my_exprs_.clear();
    for (size_t i = 0; i < my_filters_.size(); i++) {
        delete my_filters_[i];
        my_filters_[i] = nullptr;
    }
    if (expression_ != nullptr) {
        delete expression_;
        expression_ = nullptr;
    }
    my_filters_.clear();
}

}  // namespace storage
