/*
 * 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_PLAIN_DECODER_H
#define ENCODING_PLAIN_DECODER_H

#include <algorithm>
#include <cstdint>
#include <cstring>

#if defined(_MSC_VER)
#include <intrin.h>
#include <stdlib.h>
#endif

#include "encoding/decoder.h"

namespace storage {

FORCE_INLINE uint32_t plain_bswap32(uint32_t v) {
#if defined(__GNUC__) || defined(__clang__)
    return __builtin_bswap32(v);
#elif defined(_MSC_VER)
    return _byteswap_ulong(v);
#else
    return ((v & 0x000000FFu) << 24) | ((v & 0x0000FF00u) << 8) |
           ((v & 0x00FF0000u) >> 8) | ((v & 0xFF000000u) >> 24);
#endif
}

FORCE_INLINE uint64_t plain_bswap64(uint64_t v) {
#if defined(__GNUC__) || defined(__clang__)
    return __builtin_bswap64(v);
#elif defined(_MSC_VER)
    return _byteswap_uint64(v);
#else
    return ((v & 0x00000000000000FFull) << 56) |
           ((v & 0x000000000000FF00ull) << 40) |
           ((v & 0x0000000000FF0000ull) << 24) |
           ((v & 0x00000000FF000000ull) << 8) |
           ((v & 0x000000FF00000000ull) >> 8) |
           ((v & 0x0000FF0000000000ull) >> 24) |
           ((v & 0x00FF000000000000ull) >> 40) |
           ((v & 0xFF00000000000000ull) >> 56);
#endif
}

class PlainDecoder : public Decoder {
   public:
    ~PlainDecoder() override = default;
    FORCE_INLINE void reset() override { /* do nothing */
    }
    FORCE_INLINE bool has_remaining(const common::ByteStream& buffer) override {
        return buffer.has_remaining();
    }
    FORCE_INLINE int read_boolean(bool& ret_bool,
                                  common::ByteStream& in) override {
        return common::SerializationUtil::read_ui8((uint8_t&)ret_bool, in);
    }

    FORCE_INLINE int read_int32(int32_t& ret_int32,
                                common::ByteStream& in) override {
        return common::SerializationUtil::read_var_int(ret_int32, in);
    }

    FORCE_INLINE int read_int64(int64_t& ret_int64,
                                common::ByteStream& in) override {
        return common::SerializationUtil::read_i64(ret_int64, in);
    }

    FORCE_INLINE int read_float(float& ret_float,
                                common::ByteStream& in) override {
        return common::SerializationUtil::read_float(ret_float, in);
    }

    FORCE_INLINE int read_double(double& ret_double,
                                 common::ByteStream& in) override {
        return common::SerializationUtil::read_double(ret_double, in);
    }

    FORCE_INLINE int read_String(common::String& ret_String,
                                 common::PageArena& pa,
                                 common::ByteStream& in) override {
        return common::SerializationUtil::read_mystring(ret_String, &pa, in);
    }

    // ── Batch overrides ──────────────────────────────────────────────────────
    //
    // INT32: PLAIN encoding uses varint (variable stride).  Override to avoid
    // virtual dispatch per element; actual decode is still per-value.
    // No PLAIN_READ_BATCH_FIXED macro: varint has no fixed stride.
    int read_batch_int32(int32_t* out, int capacity, int& actual,
                         common::ByteStream& in) override {
        actual = 0;
        while (actual < capacity && in.has_remaining()) {
            int ret = common::SerializationUtil::read_var_int(out[actual], in);
            if (ret != common::E_OK) return ret;
            ++actual;
        }
        return common::E_OK;
    }

    // No PLAIN_SKIP_FIXED macro: varint has no fixed stride.
    int skip_int32(int count, int& skipped, common::ByteStream& in) override {
        skipped = 0;
        int32_t dummy;
        while (skipped < count && in.has_remaining()) {
            int ret = common::SerializationUtil::read_var_int(dummy, in);
            if (ret != common::E_OK) {
                return ret;
            }
            ++skipped;
        }
        return common::E_OK;
    }

    // Fixed-stride INT64 / FLOAT / DOUBLE share the same shape: when the
    // ByteStream is wrapped (contiguous buf), advance the read pointer in one
    // step and byte-swap in place; otherwise fall back to per-value reads.
    // The macros below expand into one override per type.
#define PLAIN_SKIP_FIXED(NAME, T, STRIDE, READ_ONE)                         \
    int NAME(int count, int& skipped, common::ByteStream& in) override {    \
        skipped = 0;                                                        \
        if (!in.is_wrapped()) {                                             \
            T dummy;                                                        \
            while (skipped < count && in.has_remaining()) {                 \
                int ret = READ_ONE(dummy, in);                              \
                if (ret != common::E_OK) {                                  \
                    return ret;                                             \
                }                                                           \
                ++skipped;                                                  \
            }                                                               \
            return common::E_OK;                                            \
        }                                                                   \
        skipped = static_cast<int>(std::min<uint32_t>(                      \
            in.remaining_size() / (STRIDE), static_cast<uint32_t>(count))); \
        if (skipped <= 0) {                                                 \
            skipped = 0;                                                    \
            return common::E_OK;                                            \
        }                                                                   \
        in.wrapped_buf_advance_read_pos(static_cast<uint32_t>(skipped) *    \
                                        (STRIDE));                          \
        return common::E_OK;                                                \
    }

#define PLAIN_READ_BATCH_FIXED(NAME, T, U, STRIDE, READ_ONE, BSWAP)            \
    int NAME(T* out, int capacity, int& actual, common::ByteStream& in)        \
        override {                                                             \
        actual = 0;                                                            \
        if (!in.is_wrapped()) {                                                \
            while (actual < capacity && in.has_remaining()) {                  \
                int ret = READ_ONE(out[actual], in);                           \
                if (ret != common::E_OK) {                                     \
                    return ret;                                                \
                }                                                              \
                ++actual;                                                      \
            }                                                                  \
            return common::E_OK;                                               \
        }                                                                      \
        int n = static_cast<int>(std::min<uint32_t>(                           \
            in.remaining_size() / (STRIDE), static_cast<uint32_t>(capacity))); \
        if (n <= 0) {                                                          \
            return common::E_OK;                                               \
        }                                                                      \
        const uint8_t* src =                                                   \
            (const uint8_t*)in.get_wrapped_buf() + in.read_pos();              \
        in.wrapped_buf_advance_read_pos(static_cast<uint32_t>(n) * (STRIDE));  \
        actual = n;                                                            \
        for (int i = 0; i < n; ++i) {                                          \
            U v;                                                               \
            memcpy(&v, src + i * (STRIDE), (STRIDE));                          \
            v = BSWAP(v);                                                      \
            memcpy(&out[i], &v, (STRIDE));                                     \
        }                                                                      \
        return common::E_OK;                                                   \
    }

    PLAIN_SKIP_FIXED(skip_int64, int64_t, 8,
                     common::SerializationUtil::read_i64)
    PLAIN_SKIP_FIXED(skip_float, float, 4,
                     common::SerializationUtil::read_float)
    PLAIN_SKIP_FIXED(skip_double, double, 8,
                     common::SerializationUtil::read_double)

    PLAIN_READ_BATCH_FIXED(read_batch_int64, int64_t, uint64_t, 8,
                           common::SerializationUtil::read_i64, plain_bswap64)
    PLAIN_READ_BATCH_FIXED(read_batch_float, float, uint32_t, 4,
                           common::SerializationUtil::read_float, plain_bswap32)
    PLAIN_READ_BATCH_FIXED(read_batch_double, double, uint64_t, 8,
                           common::SerializationUtil::read_double,
                           plain_bswap64)

#undef PLAIN_SKIP_FIXED
#undef PLAIN_READ_BATCH_FIXED
};

}  // end namespace storage
#endif  // ENCODING_PLAIN_DECODER_H
