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

#pragma once

#include "common/exception.h"
#include "common/status.h"
#include "exprs/hybrid_set.h"
#include "exprs/minmax_predicate.h"
#include "function_filter.h"
#include "olap/bitmap_filter_predicate.h"
#include "olap/bloom_filter_predicate.h"
#include "olap/column_predicate.h"
#include "olap/in_list_predicate.h"
#include "olap/like_column_predicate.h"
#include "runtime/define_primitive_type.h"

namespace doris {

class MinmaxFunctionTraits {
public:
    using BasePtr = MinMaxFuncBase*;
    template <PrimitiveType type, size_t N>
    static BasePtr get_function(bool null_aware) {
        using CppType = typename PrimitiveTypeTraits<type>::CppType;
        return new MinMaxNumFunc<
                std::conditional_t<std::is_same_v<CppType, StringRef>, std::string, CppType>>(
                null_aware);
    }
};

class HybridSetTraits {
public:
    using BasePtr = HybridSetBase*;
    template <PrimitiveType type, size_t N>
    static BasePtr get_function(bool null_aware) {
        using CppType = typename PrimitiveTypeTraits<type>::CppType;
        if constexpr (N >= 1 && N <= FIXED_CONTAINER_MAX_SIZE) {
            using Set = std::conditional_t<
                    std::is_same_v<CppType, StringRef>, StringSet<>,
                    HybridSet<type,
                              FixedContainer<typename PrimitiveTypeTraits<type>::CppType, N>>>;
            return new Set(null_aware);
        } else {
            using Set = std::conditional_t<
                    std::is_same_v<CppType, StringRef>, StringSet<>,
                    HybridSet<type, DynamicContainer<typename PrimitiveTypeTraits<type>::CppType>>>;
            return new Set(null_aware);
        }
    }
};

class BloomFilterTraits {
public:
    using BasePtr = BloomFilterFuncBase*;
    template <PrimitiveType type, size_t N>
    static BasePtr get_function(bool null_aware) {
        return new BloomFilterFunc<type>(null_aware);
    }
};

class BitmapFilterTraits {
public:
    using BasePtr = BitmapFilterFuncBase*;
    template <PrimitiveType type, size_t N>
    static BasePtr get_function(bool null_aware) {
        return new BitmapFilterFunc<type>(null_aware);
    }
};

template <class Traits>
class PredicateFunctionCreator {
public:
    template <PrimitiveType type, size_t N = 0>
    static typename Traits::BasePtr create(bool null_aware) {
        return Traits::template get_function<type, N>(null_aware);
    }
};

#define APPLY_FOR_PRIMTYPE(M) \
    M(TYPE_TINYINT)           \
    M(TYPE_SMALLINT)          \
    M(TYPE_INT)               \
    M(TYPE_BIGINT)            \
    M(TYPE_LARGEINT)          \
    M(TYPE_FLOAT)             \
    M(TYPE_DOUBLE)            \
    M(TYPE_DATE)              \
    M(TYPE_DATETIME)          \
    M(TYPE_DATEV2)            \
    M(TYPE_DATETIMEV2)        \
    M(TYPE_TIMESTAMPTZ)       \
    M(TYPE_CHAR)              \
    M(TYPE_VARCHAR)           \
    M(TYPE_STRING)            \
    M(TYPE_DECIMAL32)         \
    M(TYPE_DECIMAL64)         \
    M(TYPE_DECIMAL128I)       \
    M(TYPE_DECIMAL256)        \
    M(TYPE_IPV4)              \
    M(TYPE_IPV6)

template <class Traits, size_t N = 0>
typename Traits::BasePtr create_predicate_function(PrimitiveType type, bool null_aware) {
    using Creator = PredicateFunctionCreator<Traits>;

    switch (type) {
    case TYPE_BOOLEAN: {
        return Creator::template create<TYPE_BOOLEAN, N>(null_aware);
    }
    case TYPE_DECIMALV2: {
        return Creator::template create<TYPE_DECIMALV2, N>(null_aware);
    }
#define M(NAME)                                               \
    case NAME: {                                              \
        return Creator::template create<NAME, N>(null_aware); \
    }
        APPLY_FOR_PRIMTYPE(M)
#undef M
    default:
        throw Exception(ErrorCode::INTERNAL_ERROR, "predicate with type " + type_to_string(type));
    }

    return nullptr;
}

template <class Traits>
typename Traits::BasePtr create_bitmap_predicate_function(PrimitiveType type) {
    using Creator = PredicateFunctionCreator<Traits>;

    switch (type) {
    case TYPE_TINYINT:
        return Creator::template create<TYPE_TINYINT>(false);
    case TYPE_SMALLINT:
        return Creator::template create<TYPE_SMALLINT>(false);
    case TYPE_INT:
        return Creator::template create<TYPE_INT>(false);
    case TYPE_BIGINT:
        return Creator::template create<TYPE_BIGINT>(false);
    default:
        throw Exception(ErrorCode::INTERNAL_ERROR,
                        "bitmap predicate with type " + type_to_string(type));
    }

    return nullptr;
}

inline auto create_minmax_filter(PrimitiveType type, bool null_aware) {
    return create_predicate_function<MinmaxFunctionTraits>(type, null_aware);
}

template <size_t N = 0>
inline auto create_set(PrimitiveType type, bool null_aware) {
    return create_predicate_function<HybridSetTraits, N>(type, null_aware);
}

inline auto create_set(PrimitiveType type, size_t size, bool null_aware) {
    if (size == 0) {
        return create_set<0>(type, null_aware);
    } else if (size == 1) {
        return create_set<1>(type, null_aware);
    } else if (size == 2) {
        return create_set<2>(type, null_aware);
    } else if (size == 3) {
        return create_set<3>(type, null_aware);
    } else if (size == 4) {
        return create_set<4>(type, null_aware);
    } else if (size == 5) {
        return create_set<5>(type, null_aware);
    } else if (size == 6) {
        return create_set<6>(type, null_aware);
    } else if (size == 7) {
        return create_set<7>(type, null_aware);
    } else if (size == FIXED_CONTAINER_MAX_SIZE) {
        return create_set<FIXED_CONTAINER_MAX_SIZE>(type, null_aware);
    } else {
        return create_set(type, null_aware);
    }
}

template <size_t N = 0>
inline HybridSetBase* create_string_value_set(bool null_aware) {
    if constexpr (N >= 1 && N <= FIXED_CONTAINER_MAX_SIZE) {
        return new StringValueSet<FixedContainer<StringRef, N>>(null_aware);
    } else {
        return new StringValueSet(null_aware);
    }
}

inline HybridSetBase* create_string_value_set(size_t size, bool null_aware) {
    if (size == 1) {
        return create_string_value_set<1>(null_aware);
    } else if (size == 2) {
        return create_string_value_set<2>(null_aware);
    } else if (size == 3) {
        return create_string_value_set<3>(null_aware);
    } else if (size == 4) {
        return create_string_value_set<4>(null_aware);
    } else if (size == 5) {
        return create_string_value_set<5>(null_aware);
    } else if (size == 6) {
        return create_string_value_set<6>(null_aware);
    } else if (size == 7) {
        return create_string_value_set<7>(null_aware);
    } else if (size == FIXED_CONTAINER_MAX_SIZE) {
        return create_string_value_set<FIXED_CONTAINER_MAX_SIZE>(null_aware);
    } else {
        return create_string_value_set(null_aware);
    }
}

inline auto create_bloom_filter(PrimitiveType type, bool null_aware) {
    return create_predicate_function<BloomFilterTraits>(type, null_aware);
}

inline auto create_bitmap_filter(PrimitiveType type) {
    return create_bitmap_predicate_function<BitmapFilterTraits>(type);
}

template <PrimitiveType PT>
std::shared_ptr<const ColumnPredicate> create_olap_column_predicate(
        uint32_t column_id, const std::shared_ptr<BloomFilterFuncBase>& filter, const TabletColumn*,
        bool null_aware) {
    std::shared_ptr<BloomFilterFuncBase> filter_olap;
    filter_olap.reset(create_bloom_filter(PT, null_aware));
    filter_olap->light_copy(filter.get());
    // create a new filter to match the input filter and PT. For example, filter may be varchar, but PT is char
    return BloomFilterColumnPredicate<PT>::create_shared(column_id, filter_olap);
}

template <PrimitiveType PT>
std::shared_ptr<const ColumnPredicate> create_olap_column_predicate(
        uint32_t column_id, const std::shared_ptr<BitmapFilterFuncBase>& filter,
        const TabletColumn*, bool) {
    if constexpr (PT == TYPE_TINYINT || PT == TYPE_SMALLINT || PT == TYPE_INT ||
                  PT == TYPE_BIGINT) {
        return BitmapFilterColumnPredicate<PT>::create_shared(column_id, filter);
    } else {
        throw Exception(ErrorCode::INTERNAL_ERROR, "bitmap filter do not support type {}", PT);
    }
}

template <PrimitiveType PT>
std::shared_ptr<const ColumnPredicate> create_olap_column_predicate(
        uint32_t column_id, const std::shared_ptr<HybridSetBase>& filter,
        const TabletColumn* column, bool) {
    return create_in_list_predicate<PT, PredicateType::IN_LIST>(column_id, filter,
                                                                column->length());
}

template <PrimitiveType PT>
std::shared_ptr<ColumnPredicate> create_olap_column_predicate(
        uint32_t column_id, const std::shared_ptr<FunctionFilter>& filter,
        const TabletColumn* column, bool) {
    // currently only support like predicate
    if constexpr (PT == TYPE_CHAR) {
        return LikeColumnPredicate<TYPE_CHAR>::create_shared(
                filter->_opposite, column_id, filter->_fn_ctx, filter->_string_param);
    } else if constexpr (PT == TYPE_VARCHAR || PT == TYPE_STRING) {
        return LikeColumnPredicate<TYPE_STRING>::create_shared(
                filter->_opposite, column_id, filter->_fn_ctx, filter->_string_param);
    }
    throw Exception(ErrorCode::INTERNAL_ERROR, "function filter do not support type {}", PT);
}

template <typename T>
std::shared_ptr<ColumnPredicate> create_column_predicate(uint32_t column_id,
                                                         const std::shared_ptr<T>& filter,
                                                         FieldType type, const TabletColumn* column,
                                                         bool null_aware = false) {
    switch (type) {
#define M(NAME)                                                                           \
    case FieldType::OLAP_FIELD_##NAME: {                                                  \
        return create_olap_column_predicate<NAME>(column_id, filter, column, null_aware); \
    }
        APPLY_FOR_PRIMTYPE(M)
#undef M
    case FieldType::OLAP_FIELD_TYPE_DECIMAL: {
        return create_olap_column_predicate<TYPE_DECIMALV2>(column_id, filter, column, null_aware);
    }
    case FieldType::OLAP_FIELD_TYPE_BOOL: {
        return create_olap_column_predicate<TYPE_BOOLEAN>(column_id, filter, column, null_aware);
    }
    default:
        return nullptr;
    }
}

} // namespace doris
