/*
 * 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 "paimon/common/data/abstract_binary_writer.h"

#include <cassert>
#include <memory>
#include <optional>

#include "paimon/common/data/binary_array.h"
#include "paimon/common/data/binary_map.h"
#include "paimon/common/data/binary_row.h"
#include "paimon/common/data/binary_section.h"
#include "paimon/common/data/binary_string.h"
#include "paimon/common/memory/memory_segment_utils.h"
#include "paimon/data/decimal.h"
#include "paimon/data/timestamp.h"
#include "paimon/io/byte_order.h"
#include "paimon/memory/bytes.h"
#include "paimon/memory/memory_pool.h"

namespace paimon {

void AbstractBinaryWriter::WriteBytes(int32_t pos, const Bytes& bytes) {
    int32_t len = bytes.size();
    if (len <= BinarySection::MAX_FIX_PART_DATA_SIZE) {
        WriteBytesToFixLenPart(&segment_, GetFieldOffset(pos), bytes, len);
    } else {
        WriteBytesToVarLenPart(pos, bytes, len);
    }
}

void AbstractBinaryWriter::WriteString(int32_t pos, const BinaryString& input) {
    int32_t len = input.GetSizeInBytes();
    if (len <= BinarySection::MAX_FIX_PART_DATA_SIZE) {
        auto bytes = Bytes::AllocateBytes(len, pool_);
        MemorySegmentUtils::CopyToBytes({input.GetSegment()}, input.GetOffset(), bytes.get(), 0,
                                        len);
        WriteBytesToFixLenPart(&segment_, GetFieldOffset(pos), *bytes, len);
    } else {
        WriteSegmentToVarLenPart(pos, input.GetSegment(), input.GetOffset(), len);
    }
}

void AbstractBinaryWriter::WriteBinary(int32_t pos, const Bytes& bytes) {
    int32_t len = bytes.size();
    if (len <= BinarySection::MAX_FIX_PART_DATA_SIZE) {
        WriteBytesToFixLenPart(&segment_, GetFieldOffset(pos), bytes, len);
    } else {
        WriteBytesToVarLenPart(pos, bytes, len);
    }
}

void AbstractBinaryWriter::WriteStringView(int32_t pos, const std::string_view& view) {
    int32_t len = view.size();
    if (len <= BinarySection::MAX_FIX_PART_DATA_SIZE) {
        WriteBytesToFixLenPart(&segment_, GetFieldOffset(pos), view, len);
    } else {
        WriteBytesToVarLenPart(pos, view, len);
    }
}

void AbstractBinaryWriter::WriteRow(int32_t pos, const BinaryRow& input) {
    return WriteSegmentToVarLenPart(pos, input.GetSegment(), input.GetOffset(),
                                    input.GetSizeInBytes());
}

void AbstractBinaryWriter::WriteArray(int32_t pos, const BinaryArray& input) {
    return WriteSegmentToVarLenPart(pos, input.GetSegment(), input.GetOffset(),
                                    input.GetSizeInBytes());
}

void AbstractBinaryWriter::WriteMap(int32_t pos, const BinaryMap& input) {
    return WriteSegmentToVarLenPart(pos, input.GetSegment(), input.GetOffset(),
                                    input.GetSizeInBytes());
}
void AbstractBinaryWriter::WriteDecimal(int32_t pos, const std::optional<Decimal>& value,
                                        int32_t precision) {
    assert(value == std::nullopt || precision == value.value().Precision());
    if (Decimal::IsCompact(precision)) {
        assert(value != std::nullopt);
        WriteLong(pos, value.value().ToUnscaledLong());
    } else {
        // grow the global buffer before writing data.
        EnsureCapacity(16);
        // zero-out 16 bytes
        segment_.PutValue<int64_t>(cursor_, 0ll);
        segment_.PutValue<int64_t>(cursor_ + 8, 0ll);

        // Make sure Decimal object has the same scale as DecimalType.
        // Note that we may pass in null Decimal object to set null for it.
        if (value == std::nullopt) {
            SetNullBit(pos);
            SetOffsetAndSize(pos, cursor_, 0l);
        } else {
            auto bytes = value.value().ToUnscaledBytes();
            segment_.Put(cursor_, bytes, 0, bytes.size());
            SetOffsetAndSize(pos, cursor_, bytes.size());
        }
        // move the cursor forward.
        cursor_ += 16;
    }
}

void AbstractBinaryWriter::WriteTimestamp(int32_t pos, const std::optional<Timestamp>& value,
                                          int32_t precision) {
    if (Timestamp::IsCompact(precision)) {
        assert(value != std::nullopt);
        WriteLong(pos, value.value().GetMillisecond());
    } else {
        // store the nanoOfMillisecond in fixed-length part as offset and nanoOfMillisecond
        EnsureCapacity(8);

        if (value == std::nullopt) {
            SetNullBit(pos);
            // zero-out the bytes
            segment_.PutValue<int64_t>(cursor_, 0l);
            SetOffsetAndSize(pos, cursor_, 0l);
        } else {
            segment_.PutValue<int64_t>(cursor_, value.value().GetMillisecond());
            SetOffsetAndSize(pos, cursor_, value.value().GetNanoOfMillisecond());
        }
        cursor_ += 8;
    }
}

void AbstractBinaryWriter::ZeroOutPaddingBytes(int32_t num_bytes) {
    if ((num_bytes & 0x07) > 0) {
        segment_.PutValue<int64_t>(cursor_ + ((num_bytes >> 3) << 3), 0L);
    }
}

void AbstractBinaryWriter::EnsureCapacity(int32_t needed_size) {
    const int32_t length = cursor_ + needed_size;
    if (segment_.Size() < length) {
        Grow(length);
    }
}

void AbstractBinaryWriter::WriteSegmentToVarLenPart(int32_t pos, const MemorySegment& segment,
                                                    int32_t offset, int32_t size) {
    const int32_t rounded_size = RoundNumberOfBytesToNearestWord(size);
    // grow the global buffer before writing data.
    EnsureCapacity(rounded_size);
    ZeroOutPaddingBytes(size);

    segment.CopyTo(offset, &segment_, cursor_, size);
    SetOffsetAndSize(pos, cursor_, size);
    // move the cursor forward.
    cursor_ += rounded_size;
}

template <typename T>
void AbstractBinaryWriter::WriteBytesToVarLenPart(int32_t pos, const T& bytes, int32_t len) {
    const int32_t rounded_size = RoundNumberOfBytesToNearestWord(len);
    // grow the global buffer before writing data.
    EnsureCapacity(rounded_size);
    ZeroOutPaddingBytes(len);
    // Write the bytes to the variable length portion.
    segment_.Put(cursor_, bytes, 0, len);
    SetOffsetAndSize(pos, cursor_, len);
    // move the cursor forward.
    cursor_ += rounded_size;
}

void AbstractBinaryWriter::Grow(int32_t min_capacity) {
    int32_t old_capacity = segment_.Size();
    int32_t new_capacity = old_capacity + (old_capacity >> 1);
    if (new_capacity - min_capacity < 0) {
        new_capacity = min_capacity;
    }
    std::shared_ptr<Bytes> new_bytes =
        Bytes::CopyOf(*(segment_.GetOrCreateHeapMemory(pool_)), new_capacity, pool_);
    segment_ = MemorySegment::Wrap(new_bytes);
    AfterGrow();
}

int32_t AbstractBinaryWriter::RoundNumberOfBytesToNearestWord(int32_t num_bytes) {
    int32_t remainder = num_bytes & 0x07;
    if (remainder == 0) {
        return num_bytes;
    } else {
        return num_bytes + (8 - remainder);
    }
}

template <typename T>
void AbstractBinaryWriter::WriteBytesToFixLenPart(MemorySegment* segment, int32_t field_offset,
                                                  const T& bytes, int32_t len) {
    const uint64_t first_byte =
        static_cast<uint64_t>(len) | 0x80U;  // first bit is 1, low 7 bits are len
    uint64_t seven_bytes = 0U;               // real data
    if ((SystemByteOrder() == ByteOrder::PAIMON_LITTLE_ENDIAN)) {
        for (int32_t i = 0; i < len; i++) {
            seven_bytes |= (static_cast<uint64_t>(bytes[i]) & 0xFFU) << (i * 8U);
        }
    } else {
        for (int32_t i = 0; i < len; i++) {
            seven_bytes |= (static_cast<uint64_t>(bytes[i]) & 0xFFU) << ((6 - i) * 8U);
        }
    }
    const uint64_t offset_and_size = (first_byte << 56) | seven_bytes;
    segment->PutValue<int64_t>(field_offset, static_cast<int64_t>(offset_and_size));
}

}  // namespace paimon
