//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
//  This source code is licensed under both the GPLv2 (found in the
//  COPYING file in the root directory) and Apache 2.0 License
//  (found in the LICENSE.Apache file in the root directory).
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#pragma once

#include <bit>

#ifndef __APPLE__
#include <endian.h>
#endif
#include <stdint.h>
#include <string.h>

#include "olap/olap_common.h"
#include "util/slice.h"
#include "vec/common/endian.h"

namespace doris {
#include "common/compile_check_begin.h"
// TODO(zc): add encode big endian later when we need it
// use big endian when we have order requirement.
// little endian is more efficient when we use X86 CPU, so
// when we have no order needs, we prefer little endian encoding
inline void encode_fixed8(uint8_t* buf, uint8_t val) {
    *buf = val;
}

inline void encode_fixed16_le(uint8_t* buf, uint16_t val) {
    val = to_endian<std::endian::little>(val);
    memcpy(buf, &val, sizeof(val));
}

inline void encode_fixed32_le(uint8_t* buf, uint32_t val) {
    val = to_endian<std::endian::little>(val);
    memcpy(buf, &val, sizeof(val));
}

inline void encode_fixed64_le(uint8_t* buf, uint64_t val) {
    val = to_endian<std::endian::little>(val);
    memcpy(buf, &val, sizeof(val));
}

inline void encode_fixed128_le(uint8_t* buf, uint128_t val) {
    val = to_endian<std::endian::little>(val);
    memcpy(buf, &val, sizeof(val));
}

inline uint8_t decode_fixed8(const uint8_t* buf) {
    return *buf;
}

inline uint16_t decode_fixed16_le(const uint8_t* buf) {
    uint16_t res;
    memcpy(&res, buf, sizeof(res));
    return to_endian<std::endian::little>(res);
}

inline uint32_t decode_fixed32_le(const uint8_t* buf) {
    uint32_t res;
    memcpy(&res, buf, sizeof(res));
    return to_endian<std::endian::little>(res);
}

inline uint64_t decode_fixed64_le(const uint8_t* buf) {
    uint64_t res;
    memcpy(&res, buf, sizeof(res));
    return to_endian<std::endian::little>(res);
}

inline uint128_t decode_fixed128_le(const uint8_t* buf) {
    uint128_t res;
    memcpy(&res, buf, sizeof(res));
    return to_endian<std::endian::little>(res);
}

template <typename T>
void put_fixed32_le(T* dst, uint32_t val) {
    uint8_t buf[sizeof(val)];
    encode_fixed32_le(buf, val);
    dst->append((char*)buf, sizeof(buf));
}

template <typename T>
void put_fixed64_le(T* dst, uint64_t val) {
    uint8_t buf[sizeof(val)];
    encode_fixed64_le(buf, val);
    dst->append((char*)buf, sizeof(buf));
}

// Returns the length of the varint32 or varint64 encoding of "v"
inline int varint_length(uint64_t v) {
    int len = 1;
    while (v >= 128) {
        v >>= 7;
        len++;
    }
    return len;
}

template <typename T>
void put_fixed128_le(T* dst, uint128_t val) {
    uint8_t buf[sizeof(val)];
    encode_fixed128_le(buf, val);
    dst->append((char*)buf, sizeof(buf));
}

extern uint8_t* encode_varint32(uint8_t* dst, uint32_t value);
extern uint8_t* encode_varint64(uint8_t* dst, uint64_t value);

inline uint8_t* encode_varint64(uint8_t* dst, uint64_t v) {
    static const unsigned int B = 128;
    while (v >= B) {
        // Fetch low seven bits from current v, and the eight bit is marked as compression mark.
        // v | B is optimised from (v & (B-1)) | B, because result is assigned to uint8_t and other bits
        // is cleared by implicit conversion.
        *(dst++) = uint8_t(v | B);
        v >>= 7;
    }
    *(dst++) = static_cast<unsigned char>(v);
    return dst;
}

extern const uint8_t* decode_varint32_ptr_fallback(const uint8_t* p, const uint8_t* limit,
                                                   uint32_t* value);

inline const uint8_t* decode_varint32_ptr(const uint8_t* ptr, const uint8_t* limit,
                                          uint32_t* value) {
    if (ptr < limit) {
        uint32_t result = *ptr;
        if ((result & 128) == 0) {
            *value = result;
            return ptr + 1;
        }
    }
    return decode_varint32_ptr_fallback(ptr, limit, value);
}

extern const uint8_t* decode_varint64_ptr(const uint8_t* p, const uint8_t* limit, uint64_t* value);

template <typename T>
void put_varint32(T* dst, uint32_t v) {
    uint8_t buf[16];
    uint8_t* ptr = encode_varint32(buf, v);
    dst->append((char*)buf, static_cast<size_t>(ptr - buf));
}

template <typename T>
void put_varint64(T* dst, uint64_t v) {
    uint8_t buf[16];
    uint8_t* ptr = encode_varint64(buf, v);
    dst->append((char*)buf, static_cast<size_t>(ptr - buf));
}

template <typename T>
void put_length_prefixed_slice(T* dst, const Slice& value) {
    put_varint32(dst, uint32_t(value.get_size()));
    dst->append(value.get_data(), value.get_size());
}

template <typename T>
void put_varint64_varint32(T* dst, uint64_t v1, uint32_t v2) {
    uint8_t buf[16];
    uint8_t* ptr = encode_varint64(buf, v1);
    ptr = encode_varint32(ptr, v2);
    dst->append((char*)buf, static_cast<size_t>(ptr - buf));
}

// parse a varint32 from the start of `input` into `val`.
// on success, return true and advance `input` past the parsed value.
// on failure, return false and `input` is not modified.
inline bool get_varint32(Slice* input, uint32_t* val) {
    const auto* p = (const uint8_t*)input->data;
    const uint8_t* limit = p + input->size;
    const uint8_t* q = decode_varint32_ptr(p, limit, val);
    if (q == nullptr) {
        return false;
    } else {
        *input = Slice(q, limit - q);
        return true;
    }
}

// parse a varint64 from the start of `input` into `val`.
// on success, return true and advance `input` past the parsed value.
// on failure, return false and `input` is not modified.
inline bool get_varint64(Slice* input, uint64_t* val) {
    const auto* p = (const uint8_t*)input->data;
    const uint8_t* limit = p + input->size;
    const uint8_t* q = decode_varint64_ptr(p, limit, val);
    if (q == nullptr) {
        return false;
    } else {
        *input = Slice(q, limit - q);
        return true;
    }
}

// parse a length-prefixed-slice from the start of `input` into `val`.
// on success, return true and advance `input` past the parsed value.
// on failure, return false and `input` may or may not be modified.
inline bool get_length_prefixed_slice(Slice* input, Slice* val) {
    uint32_t len;
    if (get_varint32(input, &len) && input->get_size() >= len) {
        *val = Slice(input->get_data(), len);
        input->remove_prefix(len);
        return true;
    } else {
        return false;
    }
}
#include "common/compile_check_end.h"
} // namespace doris
