// 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 "olap/null_predicate.h"

#include <string.h>

#include <roaring/roaring.hh>

#include "olap/rowset/segment_v2/bitmap_index_reader.h"
#include "olap/rowset/segment_v2/inverted_index_cache.h"
#include "olap/rowset/segment_v2/inverted_index_reader.h"
#include "vec/columns/column.h"
#include "vec/columns/column_nullable.h"
#include "vec/runtime/vdatetime_value.h"

using namespace doris::vectorized;

namespace doris {

NullPredicate::NullPredicate(uint32_t column_id, bool is_null, bool opposite)
        : ColumnPredicate(column_id), _is_null(opposite != is_null) {}

PredicateType NullPredicate::type() const {
    return _is_null ? PredicateType::IS_NULL : PredicateType::IS_NOT_NULL;
}

Status NullPredicate::evaluate(BitmapIndexIterator* iterator, uint32_t num_rows,
                               roaring::Roaring* roaring) const {
    if (iterator != nullptr) {
        roaring::Roaring null_bitmap;
        RETURN_IF_ERROR(iterator->read_null_bitmap(&null_bitmap));
        if (_is_null) {
            *roaring &= null_bitmap;
        } else {
            *roaring -= null_bitmap;
        }
    }
    return Status::OK();
}

Status NullPredicate::evaluate(const vectorized::IndexFieldNameAndTypePair& name_with_type,
                               IndexIterator* iterator, uint32_t num_rows,
                               roaring::Roaring* bitmap) const {
    if (iterator->has_null()) {
        InvertedIndexQueryCacheHandle null_bitmap_cache_handle;
        RETURN_IF_ERROR(iterator->read_null_bitmap(&null_bitmap_cache_handle));
        std::shared_ptr<roaring::Roaring> null_bitmap = null_bitmap_cache_handle.get_bitmap();

        if (null_bitmap) {
            if (_is_null) {
                *bitmap &= *null_bitmap; // Keep only nulls in bitmap if _is_null is true
            } else {
                *bitmap -= *null_bitmap; // Remove nulls from bitmap if _is_null is false
            }
        } else if (_is_null) {
            *bitmap = roaring::Roaring(); // Reset bitmap to an empty bitmap
        }
    } else if (_is_null) {
        *bitmap = roaring::Roaring(); // Reset bitmap to an empty bitmap
    }

    return Status::OK();
}

uint16_t NullPredicate::_evaluate_inner(const vectorized::IColumn& column, uint16_t* sel,
                                        uint16_t size) const {
    uint16_t new_size = 0;
    if (auto* nullable = check_and_get_column<ColumnNullable>(column)) {
        if (!nullable->has_null()) {
            return _is_null ? 0 : size;
        }
        auto& pred_col = nullable->get_null_map_data();
        constexpr bool is_nullable = true;
#define EVALUATE_WITH_NULL_IMPL(IDX) pred_col[IDX] == _is_null
#define EVALUATE_WITHOUT_NULL_IMPL(IDX) true
        EVALUATE_BY_SELECTOR(EVALUATE_WITH_NULL_IMPL, EVALUATE_WITHOUT_NULL_IMPL)
#undef EVALUATE_WITH_NULL_IMPL
#undef EVALUATE_WITHOUT_NULL_IMPL
        return new_size;
    } else {
        if (_is_null) return 0;
    }
    return size;
}

void NullPredicate::evaluate_or(const IColumn& column, const uint16_t* sel, uint16_t size,
                                bool* flags) const {
    if (auto* nullable = check_and_get_column<ColumnNullable>(column)) {
        if (!nullable->has_null()) {
            if (!_is_null) {
                memset(flags, true, size);
            }
        } else {
            auto& null_map = nullable->get_null_map_data();
            for (uint16_t i = 0; i < size; ++i) {
                if (flags[i]) continue;
                uint16_t idx = sel[i];
                flags[i] |= (null_map[idx] == _is_null);
            }
        }
    } else {
        if (!_is_null) memset(flags, true, size);
    }
}

void NullPredicate::evaluate_and(const IColumn& column, const uint16_t* sel, uint16_t size,
                                 bool* flags) const {
    if (auto* nullable = check_and_get_column<ColumnNullable>(column)) {
        if (!nullable->has_null()) {
            if (_is_null) {
                memset(flags, false, size);
            }
        } else {
            auto& null_map = nullable->get_null_map_data();
            for (uint16_t i = 0; i < size; ++i) {
                if (flags[i]) continue;
                uint16_t idx = sel[i];
                flags[i] &= (null_map[idx] == _is_null);
            }
        }
    } else {
        if (_is_null) memset(flags, false, size);
    }
}

void NullPredicate::evaluate_vec(const vectorized::IColumn& column, uint16_t size,
                                 bool* flags) const {
    if (auto* nullable = check_and_get_column<ColumnNullable>(column)) {
        if (!nullable->has_null()) {
            memset(flags, !_is_null, size);
        }
        auto& null_map = nullable->get_null_map_data();
        for (uint16_t i = 0; i < size; ++i) {
            flags[i] = (null_map[i] == _is_null);
        }
    } else {
        if (_is_null) memset(flags, false, size);
    }
}

} //namespace doris
