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

#ifndef ENCODING_TS2DIFF_ENCODER_H
#define ENCODING_TS2DIFF_ENCODER_H

#include <sys/types.h>

#include "common/allocator/alloc_base.h"
#include "common/allocator/byte_stream.h"
#include "encoder.h"

#ifdef ENABLE_SIMD
#include "simde/x86/avx2.h"
#endif

namespace storage {

template <typename T>
struct SIMDOps;

template <>
struct SIMDOps<int32_t> {
#ifdef ENABLE_SIMD
    static void rebase(int32_t* arr, int32_t min_val, size_t size) {
        const simde__m128i min_vec = simde_mm_set1_epi32(min_val);
        size_t i = 0;
        for (; i + 3 < size; i += 4) {
            simde__m128i vec = simde_mm_loadu_si128(
                reinterpret_cast<const simde__m128i*>(arr + i));
            vec = simde_mm_sub_epi32(vec, min_vec);
            simde_mm_storeu_si128(reinterpret_cast<simde__m128i*>(arr + i),
                                  vec);
        }
        for (; i < size; ++i) {
            arr[i] -= min_val;
        }
    }
#else
    static void rebase(int32_t* arr, int32_t min_val, size_t size) {
        for (size_t i = 0; i < size; ++i) {
            arr[i] -= min_val;
        }
    }
#endif
};

template <>
struct SIMDOps<int64_t> {
#ifdef ENABLE_SIMD
    static void rebase(int64_t* arr, int64_t min_val, size_t size) {
        const simde__m256i min_vec = simde_mm256_set1_epi64x(min_val);
        size_t i = 0;
        for (; i + 3 < size; i += 4) {
            simde__m256i vec = simde_mm256_loadu_si256(
                reinterpret_cast<const simde__m256i*>(arr + i));
            vec = simde_mm256_sub_epi64(vec, min_vec);
            simde_mm256_storeu_si256(reinterpret_cast<simde__m256i*>(arr + i),
                                     vec);
        }
        for (; i < size; ++i) {
            arr[i] -= min_val;
        }
    }
#else
    static void rebase(int64_t* arr, int64_t min_val, size_t size) {
        for (size_t i = 0; i < size; ++i) {
            arr[i] -= min_val;
        }
    }
#endif
};

template <typename T>
class TS2DIFFEncoder : public Encoder {
   public:
    TS2DIFFEncoder() { init(); }

    ~TS2DIFFEncoder() { destroy(); }

    void reset() override { write_index_ = -1; }

    void init() {
        block_size_ = 128;
        // block_size_ = 16;
        delta_arr_ = (T*)common::mem_alloc(sizeof(T) * block_size_,
                                           common::MOD_TS2DIFF_OBJ);
        write_index_ = -1;
        bits_left_ = 8;
        buffer_ = 0;
        delta_arr_min_ = 0;
        delta_arr_max_ = 0;
        first_value_ = 0;
        previous_value_ = 0;
    }

    void destroy() override {
        if (delta_arr_ != nullptr) {
            common::mem_free(delta_arr_);
            delta_arr_ = nullptr;
        }
    }

    void write_bits(int64_t value, int bits, common::ByteStream& out_stream) {
        while (bits > 0) {
            int shift = bits - bits_left_;
            if (shift >= 0) {
                buffer_ |=
                    (uint8_t)((value >> shift) & ((1 << bits_left_) - 1));
                bits -= bits_left_;
                bits_left_ = 0;
            } else {
                shift = bits_left_ - bits;
                buffer_ |= (uint8_t)(value << shift);
                bits_left_ -= bits;
                bits = 0;
            }
            flush_byte_if_full(out_stream);
        }
    }

    void flush_remaining(common::ByteStream& out_stream) {
        // FIXME bits_left_ != 0 does not means something to be flushed. (=8)
        if (bits_left_ != 0 && bits_left_ != 8) {
            bits_left_ = 0;
            flush_byte_if_full(out_stream);
        }
    }

    void flush_byte_if_full(common::ByteStream& out_stream) {
        if (bits_left_ == 0) {
            out_stream.write_buf(&buffer_, 1);
            buffer_ = 0;
            bits_left_ = 8;
        }
    }

    void rebase_arr(int i) { delta_arr_[i] = delta_arr_[i] - delta_arr_min_; }

    int cal_bit_width(T n) {
        int bit_width = 0;
        while (n > 0) {
            bit_width++;
            n >>= 1;
        }
        return bit_width;
    }

    int do_encode(T value, common::ByteStream& out_stream);
    int encode(bool value, common::ByteStream& out_stream) override;
    int encode(int32_t value, common::ByteStream& out_stream) override;
    int encode(int64_t value, common::ByteStream& out_stream) override;
    int encode(float value, common::ByteStream& out_stream) override;
    int encode(double value, common::ByteStream& out_stream) override;
    int encode(common::String value, common::ByteStream& out_stream) override;

    int encode_batch(const int32_t* values, uint32_t count,
                     common::ByteStream& out_stream) override;
    int encode_batch(const int64_t* values, uint32_t count,
                     common::ByteStream& out_stream) override;

    int flush(common::ByteStream& out_stream) override;

    int get_max_byte_size() override {
        // The meaning of 24 is: index(4)+width(4)+minDeltaBase(8)+firstValue(8)
        return 24 + write_index_ * 8;
    }

   public:
    int block_size_;
    T* delta_arr_;
    T first_value_;
    T previous_value_;
    T delta_arr_min_;
    T delta_arr_max_;
    uint8_t buffer_;
    int bits_left_;
    int write_index_;
};

template <typename T>
int TS2DIFFEncoder<T>::do_encode(T value, common::ByteStream& out_stream) {
    if (write_index_ == -1) {
        first_value_ = value;
        previous_value_ = first_value_;
        write_index_++;
        return common::E_OK;
    }
    // Calculate the delta between the current value and the previous_value_
    T delta = value - previous_value_;
    previous_value_ = value;
    if (write_index_ == 0) {
        delta_arr_max_ = delta;
        delta_arr_min_ = delta;
    }
    if (delta > delta_arr_max_) {
        delta_arr_max_ = delta;
    }
    if (delta < delta_arr_min_) {
        delta_arr_min_ = delta;
    }

    delta_arr_[write_index_] = delta;
    write_index_++;

    if (write_index_ >= block_size_) {
        return flush(out_stream);
    }
    return common::E_OK;
}

template <>
inline int TS2DIFFEncoder<int32_t>::flush(common::ByteStream& out_stream) {
    int ret = common::E_OK;
    if (write_index_ == -1) {
        return common::E_OK;
    }
    // Subtract the minimum value for each delta_arr_ item
    SIMDOps<int32_t>::rebase(delta_arr_, delta_arr_min_, write_index_);
    // Calculate the bit length of each value to writer
    int bit_width = cal_bit_width(delta_arr_max_ - delta_arr_min_);
    // writer header
    common::SerializationUtil::write_ui32(write_index_, out_stream);
    common::SerializationUtil::write_ui32(bit_width, out_stream);
    common::SerializationUtil::write_ui32(delta_arr_min_, out_stream);
    common::SerializationUtil::write_ui32(first_value_, out_stream);
    // writer data
    for (int i = 0; i < write_index_; i++) {
        write_bits(delta_arr_[i], bit_width, out_stream);
    }
    flush_remaining(out_stream);
    reset();
    return ret;
}

template <>
inline int TS2DIFFEncoder<int64_t>::flush(common::ByteStream& out_stream) {
    int ret = common::E_OK;
    if (write_index_ == -1) {
        return common::E_OK;
    }
    // Subtract the minimum value for each delta_arr_ item
    SIMDOps<int64_t>::rebase(delta_arr_, delta_arr_min_, write_index_);
    // Calculate the bit length of each value to writer
    int bit_width = cal_bit_width(delta_arr_max_ - delta_arr_min_);
    // writer header
    common::SerializationUtil::write_i32(write_index_, out_stream);
    common::SerializationUtil::write_i32(bit_width, out_stream);
    common::SerializationUtil::write_i64(delta_arr_min_, out_stream);
    common::SerializationUtil::write_i64(first_value_, out_stream);
    // writer data
    for (int i = 0; i < write_index_; i++) {
        write_bits(delta_arr_[i], bit_width, out_stream);
    }
    flush_remaining(out_stream);
    reset();  // 语义，writeIndex=-1;
    return ret;
}

// ============================================================================
// Batch encode: INT32
// Adjacent-difference removes sequential dependency; SIMD for delta + min/max.
// ============================================================================

template <>
inline int TS2DIFFEncoder<int32_t>::encode_batch(
    const int32_t* values, uint32_t count, common::ByteStream& out_stream) {
    int ret = common::E_OK;
    uint32_t offset = 0;

    while (offset < count) {
        // Start of new block: store first_value
        if (write_index_ == -1) {
            first_value_ = values[offset];
            previous_value_ = first_value_;
            write_index_ = 0;
            offset++;
            continue;
        }

        // How many deltas fit in current block
        uint32_t space = static_cast<uint32_t>(block_size_) - write_index_;
        uint32_t batch = std::min(count - offset, space);

        // ── Adjacent difference: delta[i] = values[i] - values[i-1] ──
        // First delta uses previous_value_
        delta_arr_[write_index_] = values[offset] - previous_value_;

        uint32_t i = 1;
#ifdef ENABLE_SIMD
        // SIMD: 4 adjacent differences at a time
        for (; i + 3 < batch; i += 4) {
            simde__m128i cur = simde_mm_loadu_si128(
                reinterpret_cast<const simde__m128i*>(values + offset + i));
            simde__m128i prv = simde_mm_loadu_si128(
                reinterpret_cast<const simde__m128i*>(values + offset + i - 1));
            simde__m128i diff = simde_mm_sub_epi32(cur, prv);
            simde_mm_storeu_si128(
                reinterpret_cast<simde__m128i*>(delta_arr_ + write_index_ + i),
                diff);
        }
#endif
        for (; i < batch; i++) {
            delta_arr_[write_index_ + i] =
                values[offset + i] - values[offset + i - 1];
        }
        previous_value_ = values[offset + batch - 1];

        // ── Min/max of new deltas ──
        int32_t local_min = delta_arr_[write_index_];
        int32_t local_max = delta_arr_[write_index_];

        uint32_t j = 1;
#ifdef ENABLE_SIMD
        if (batch >= 5) {
            simde__m128i vmin = simde_mm_set1_epi32(local_min);
            simde__m128i vmax = vmin;
            for (; j + 3 < batch; j += 4) {
                simde__m128i v =
                    simde_mm_loadu_si128(reinterpret_cast<const simde__m128i*>(
                        delta_arr_ + write_index_ + j));
                vmin = simde_mm_min_epi32(vmin, v);
                vmax = simde_mm_max_epi32(vmax, v);
            }
            // Horizontal reduce
            int32_t tmp[4];
            simde_mm_storeu_si128(reinterpret_cast<simde__m128i*>(tmp), vmin);
            for (int k = 0; k < 4; k++)
                if (tmp[k] < local_min) local_min = tmp[k];
            simde_mm_storeu_si128(reinterpret_cast<simde__m128i*>(tmp), vmax);
            for (int k = 0; k < 4; k++)
                if (tmp[k] > local_max) local_max = tmp[k];
        }
#endif
        for (; j < batch; j++) {
            int32_t d = delta_arr_[write_index_ + j];
            if (d < local_min) local_min = d;
            if (d > local_max) local_max = d;
        }

        // Merge with block min/max
        if (write_index_ == 0) {
            delta_arr_min_ = local_min;
            delta_arr_max_ = local_max;
        } else {
            if (local_min < delta_arr_min_) delta_arr_min_ = local_min;
            if (local_max > delta_arr_max_) delta_arr_max_ = local_max;
        }

        write_index_ += batch;
        offset += batch;

        if (write_index_ >= block_size_) {
            if (RET_FAIL(flush(out_stream))) return ret;
        }
    }
    return ret;
}

// ============================================================================
// Batch encode: INT64
// ============================================================================

template <>
inline int TS2DIFFEncoder<int64_t>::encode_batch(
    const int64_t* values, uint32_t count, common::ByteStream& out_stream) {
    int ret = common::E_OK;
    uint32_t offset = 0;

    while (offset < count) {
        if (write_index_ == -1) {
            first_value_ = values[offset];
            previous_value_ = first_value_;
            write_index_ = 0;
            offset++;
            continue;
        }

        uint32_t space = static_cast<uint32_t>(block_size_) - write_index_;
        uint32_t batch = std::min(count - offset, space);

        // Adjacent difference
        delta_arr_[write_index_] = values[offset] - previous_value_;

        uint32_t i = 1;
#ifdef ENABLE_SIMD
        // SIMD: 2 adjacent differences at a time (128-bit, native NEON)
        for (; i + 1 < batch; i += 2) {
            simde__m128i cur = simde_mm_loadu_si128(
                reinterpret_cast<const simde__m128i*>(values + offset + i));
            simde__m128i prv = simde_mm_loadu_si128(
                reinterpret_cast<const simde__m128i*>(values + offset + i - 1));
            simde__m128i diff = simde_mm_sub_epi64(cur, prv);
            simde_mm_storeu_si128(
                reinterpret_cast<simde__m128i*>(delta_arr_ + write_index_ + i),
                diff);
        }
#endif
        for (; i < batch; i++) {
            delta_arr_[write_index_ + i] =
                values[offset + i] - values[offset + i - 1];
        }
        previous_value_ = values[offset + batch - 1];

        // Min/max (scalar — no efficient 64-bit SIMD min/max before AVX-512)
        int64_t local_min = delta_arr_[write_index_];
        int64_t local_max = delta_arr_[write_index_];
        for (uint32_t j = 1; j < batch; j++) {
            int64_t d = delta_arr_[write_index_ + j];
            if (d < local_min) local_min = d;
            if (d > local_max) local_max = d;
        }

        if (write_index_ == 0) {
            delta_arr_min_ = local_min;
            delta_arr_max_ = local_max;
        } else {
            if (local_min < delta_arr_min_) delta_arr_min_ = local_min;
            if (local_max > delta_arr_max_) delta_arr_max_ = local_max;
        }

        write_index_ += batch;
        offset += batch;

        if (write_index_ >= block_size_) {
            if (RET_FAIL(flush(out_stream))) return ret;
        }
    }
    return ret;
}

// Default: unsupported types fall back to base class loop
template <typename T>
int TS2DIFFEncoder<T>::encode_batch(const int32_t* values, uint32_t count,
                                    common::ByteStream& out) {
    return Encoder::encode_batch(values, count, out);
}
template <typename T>
int TS2DIFFEncoder<T>::encode_batch(const int64_t* values, uint32_t count,
                                    common::ByteStream& out) {
    return Encoder::encode_batch(values, count, out);
}

class FloatTS2DIFFEncoder : public TS2DIFFEncoder<int32_t> {
   public:
    int do_encode(float value, common::ByteStream& out_stream) {
        int32_t value_int = common::float_to_int(value);
        return TS2DIFFEncoder<int32_t>::do_encode(value_int, out_stream);
    }
    int encode(bool value, common::ByteStream& out_stream);
    int encode(int32_t value, common::ByteStream& out_stream);
    int encode(int64_t value, common::ByteStream& out_stream);
    int encode(float value, common::ByteStream& out_stream);
    int encode(double value, common::ByteStream& out_stream);
};

class DoubleTS2DIFFEncoder : public TS2DIFFEncoder<int64_t> {
   public:
    int do_encode(double value, common::ByteStream& out_stream) {
        int64_t value_long = common::double_to_long(value);
        return TS2DIFFEncoder<int64_t>::do_encode(value_long, out_stream);
    }
    int encode(bool value, common::ByteStream& out_stream);
    int encode(int32_t value, common::ByteStream& out_stream);
    int encode(int64_t value, common::ByteStream& out_stream);
    int encode(float value, common::ByteStream& out_stream);
    int encode(double value, common::ByteStream& out_stream);
};

typedef TS2DIFFEncoder<int32_t> IntTS2DIFFEncoder;
typedef TS2DIFFEncoder<int64_t> LongTS2DIFFEncoder;

// wrap as Encoder
template <>
FORCE_INLINE int IntTS2DIFFEncoder::encode(bool value,
                                           common::ByteStream& out) {
    return common::E_TYPE_NOT_MATCH;
}
template <>
FORCE_INLINE int IntTS2DIFFEncoder::encode(int32_t value,
                                           common::ByteStream& out) {
    return do_encode(value, out);
}
template <>
FORCE_INLINE int IntTS2DIFFEncoder::encode(int64_t value,
                                           common::ByteStream& out) {
    return common::E_TYPE_NOT_MATCH;
}
template <>
FORCE_INLINE int IntTS2DIFFEncoder::encode(float value,
                                           common::ByteStream& out) {
    return common::E_TYPE_NOT_MATCH;
}
template <>
FORCE_INLINE int IntTS2DIFFEncoder::encode(double value,
                                           common::ByteStream& out) {
    return common::E_TYPE_NOT_MATCH;
}
template <>
FORCE_INLINE int IntTS2DIFFEncoder::encode(common::String value,
                                           common::ByteStream& out) {
    return common::E_TYPE_NOT_MATCH;
}

template <>
FORCE_INLINE int LongTS2DIFFEncoder::encode(bool value,
                                            common::ByteStream& out) {
    return common::E_TYPE_NOT_MATCH;
}
template <>
FORCE_INLINE int LongTS2DIFFEncoder::encode(int32_t value,
                                            common::ByteStream& out) {
    return common::E_TYPE_NOT_MATCH;
}
template <>
FORCE_INLINE int LongTS2DIFFEncoder::encode(int64_t value,
                                            common::ByteStream& out) {
    return do_encode(value, out);
}
template <>
FORCE_INLINE int LongTS2DIFFEncoder::encode(float value,
                                            common::ByteStream& out) {
    return common::E_TYPE_NOT_MATCH;
}
template <>
FORCE_INLINE int LongTS2DIFFEncoder::encode(double value,
                                            common::ByteStream& out) {
    return common::E_TYPE_NOT_MATCH;
}
template <>
FORCE_INLINE int LongTS2DIFFEncoder::encode(common::String value,
                                            common::ByteStream& out) {
    return common::E_TYPE_NOT_MATCH;
}
FORCE_INLINE int FloatTS2DIFFEncoder::encode(bool value,
                                             common::ByteStream& out) {
    return common::E_TYPE_NOT_MATCH;
}
FORCE_INLINE int FloatTS2DIFFEncoder::encode(int32_t value,
                                             common::ByteStream& out) {
    return common::E_TYPE_NOT_MATCH;
}
FORCE_INLINE int FloatTS2DIFFEncoder::encode(int64_t value,
                                             common::ByteStream& out) {
    return common::E_TYPE_NOT_MATCH;
}
FORCE_INLINE int FloatTS2DIFFEncoder::encode(float value,
                                             common::ByteStream& out) {
    return do_encode(value, out);
}
FORCE_INLINE int FloatTS2DIFFEncoder::encode(double value,
                                             common::ByteStream& out) {
    return common::E_TYPE_NOT_MATCH;
}

FORCE_INLINE int DoubleTS2DIFFEncoder::encode(bool value,
                                              common::ByteStream& out) {
    return common::E_TYPE_NOT_MATCH;
}
FORCE_INLINE int DoubleTS2DIFFEncoder::encode(int32_t value,
                                              common::ByteStream& out) {
    return common::E_TYPE_NOT_MATCH;
}
FORCE_INLINE int DoubleTS2DIFFEncoder::encode(int64_t value,
                                              common::ByteStream& out) {
    return common::E_TYPE_NOT_MATCH;
}
FORCE_INLINE int DoubleTS2DIFFEncoder::encode(float value,
                                              common::ByteStream& out) {
    return common::E_TYPE_NOT_MATCH;
}
FORCE_INLINE int DoubleTS2DIFFEncoder::encode(double value,
                                              common::ByteStream& out) {
    return do_encode(value, out);
}

}  // end namespace storage
#endif  // ENCODING_TS2DIFF_ENCODER_H
