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

#include <cmath>
#include <cstdint>
#include <limits>
#include <vector>

#include "encoding/decoder_factory.h"
#include "encoding/encoder_factory.h"
#include "encoding/rlbe_decoder.h"
#include "encoding/rlbe_encoder.h"

namespace storage {

namespace {

void append_bits(std::vector<uint8_t>& bytes, int& bit_count, uint32_t value,
                 int width) {
    for (int i = width - 1; i >= 0; --i) {
        if (bytes.empty() || bit_count == 8) {
            bytes.push_back(0);
            bit_count = 0;
        }
        bytes.back() =
            static_cast<uint8_t>((bytes.back() << 1) | ((value >> i) & 1));
        ++bit_count;
    }
}

}  // namespace

TEST(RLBECodecTest, Int32RoundTrip) {
    IntRLBEEncoder encoder;
    IntRLBEDecoder decoder;
    common::ByteStream stream(1024, common::MOD_DEFAULT);
    std::vector<int32_t> values = {7, 9, 11, 11, 11, -7, -9, 0, INT32_MAX};
    for (int32_t value : values) {
        ASSERT_EQ(encoder.encode(value, stream), common::E_OK);
    }
    ASSERT_EQ(encoder.flush(stream), common::E_OK);

    for (int32_t expected : values) {
        ASSERT_TRUE(decoder.has_remaining(stream));
        int32_t actual = 0;
        ASSERT_EQ(decoder.read_int32(actual, stream), common::E_OK);
        EXPECT_EQ(actual, expected);
    }
    EXPECT_FALSE(decoder.has_remaining(stream));
}

TEST(RLBECodecTest, Int64RoundTrip) {
    LongRLBEEncoder encoder;
    LongRLBEDecoder decoder;
    common::ByteStream stream(1024, common::MOD_DEFAULT);
    std::vector<int64_t> values = {
        7,   9,   11,           INT64_C(1) << 40, (INT64_C(1) << 40) + 3,
        -17, -23, INT64_MAX - 7};
    for (int64_t value : values) {
        ASSERT_EQ(encoder.encode(value, stream), common::E_OK);
    }
    ASSERT_EQ(encoder.flush(stream), common::E_OK);

    for (int64_t expected : values) {
        ASSERT_TRUE(decoder.has_remaining(stream));
        int64_t actual = 0;
        ASSERT_EQ(decoder.read_int64(actual, stream), common::E_OK);
        EXPECT_EQ(actual, expected);
    }
    EXPECT_FALSE(decoder.has_remaining(stream));
}

TEST(RLBECodecTest, FloatRoundTripWithSpecialValues) {
    FloatRLBEEncoder encoder;
    FloatRLBEDecoder decoder;
    common::ByteStream stream(1024, common::MOD_DEFAULT);
    std::vector<float> values = {934.02F,
                                 122.86F,
                                 33.15F,
                                 33.15F,
                                 std::numeric_limits<float>::infinity(),
                                 -std::numeric_limits<float>::infinity(),
                                 std::numeric_limits<float>::quiet_NaN()};
    for (float value : values) {
        ASSERT_EQ(encoder.encode(value, stream), common::E_OK);
    }
    ASSERT_EQ(encoder.flush(stream), common::E_OK);

    for (float expected : values) {
        ASSERT_TRUE(decoder.has_remaining(stream));
        float actual = 0;
        ASSERT_EQ(decoder.read_float(actual, stream), common::E_OK);
        if (std::isnan(expected)) {
            EXPECT_TRUE(std::isnan(actual));
        } else {
            EXPECT_EQ(std::signbit(actual), std::signbit(expected));
            EXPECT_FLOAT_EQ(actual, expected);
        }
    }
    EXPECT_FALSE(decoder.has_remaining(stream));
}

TEST(RLBECodecTest, DoubleRoundTripWithRepeatedFlushes) {
    common::ByteStream stream(1024, common::MOD_DEFAULT);
    std::vector<double> values = {934.02,
                                  122.86,
                                  33.15,
                                  33.15,
                                  -7.101,
                                  -9.101,
                                  std::numeric_limits<double>::infinity(),
                                  std::numeric_limits<double>::quiet_NaN()};

    for (int repeat = 0; repeat < 2; ++repeat) {
        DoubleRLBEEncoder encoder;
        for (double value : values) {
            ASSERT_EQ(encoder.encode(value, stream), common::E_OK);
        }
        ASSERT_EQ(encoder.flush(stream), common::E_OK);
    }

    DoubleRLBEDecoder decoder;
    for (int repeat = 0; repeat < 2; ++repeat) {
        for (double expected : values) {
            ASSERT_TRUE(decoder.has_remaining(stream));
            double actual = 0;
            ASSERT_EQ(decoder.read_double(actual, stream), common::E_OK);
            if (std::isnan(expected)) {
                EXPECT_TRUE(std::isnan(actual));
            } else {
                EXPECT_EQ(std::signbit(actual), std::signbit(expected));
                EXPECT_DOUBLE_EQ(actual, expected);
            }
        }
    }
    EXPECT_FALSE(decoder.has_remaining(stream));
}

TEST(RLBECodecTest, FactoryAllocatesRLBECodecs) {
    Encoder* float_encoder =
        EncoderFactory::alloc_value_encoder(common::RLBE, common::FLOAT);
    Decoder* float_decoder =
        DecoderFactory::alloc_value_decoder(common::RLBE, common::FLOAT);
    Encoder* double_encoder =
        EncoderFactory::alloc_value_encoder(common::RLBE, common::DOUBLE);
    Decoder* double_decoder =
        DecoderFactory::alloc_value_decoder(common::RLBE, common::DOUBLE);

    ASSERT_NE(float_encoder, nullptr);
    ASSERT_NE(float_decoder, nullptr);
    ASSERT_NE(double_encoder, nullptr);
    ASSERT_NE(double_decoder, nullptr);

    EncoderFactory::free(float_encoder);
    DecoderFactory::free(float_decoder);
    EncoderFactory::free(double_encoder);
    DecoderFactory::free(double_decoder);
}

TEST(RLBECodecTest, RejectsInvalidBlockSize) {
    std::vector<uint8_t> bytes(4, 0);
    common::ByteStream stream;
    stream.wrap_from(reinterpret_cast<const char*>(bytes.data()), bytes.size());
    IntRLBEDecoder decoder;
    int32_t value = 0;
    EXPECT_EQ(decoder.read_int32(value, stream), common::E_DECODE_ERR);
}

TEST(RLBECodecTest, RejectsRunLengthBeyondBlock) {
    std::vector<uint8_t> bytes;
    int bit_count = 0;
    append_bits(bytes, bit_count, 1, 32);     // block size
    append_bits(bytes, bit_count, 1, 6);      // segment length (int32 RLBE)
    append_bits(bytes, bit_count, 0b011, 3);  // Fibonacci code for run length 2
    append_bits(bytes, bit_count, 0, 2);      // delta payload (not reached)
    bytes.back() <<= (8 - bit_count);

    common::ByteStream stream;
    stream.wrap_from(reinterpret_cast<const char*>(bytes.data()), bytes.size());
    IntRLBEDecoder decoder;
    int32_t value = 0;
    EXPECT_EQ(decoder.read_int32(value, stream), common::E_DECODE_ERR);
}

TEST(RLBECodecTest, RejectsInvalidIntSegmentLength) {
    for (int segment_length : {0, 33}) {
        std::vector<uint8_t> bytes;
        int bit_count = 0;
        append_bits(bytes, bit_count, 1, 32);  // block size
        append_bits(bytes, bit_count, static_cast<uint32_t>(segment_length),
                    6);  // segment length
        bytes.back() <<= (8 - bit_count);

        common::ByteStream stream;
        stream.wrap_from(reinterpret_cast<const char*>(bytes.data()),
                         bytes.size());
        IntRLBEDecoder decoder;
        int32_t value = 0;
        EXPECT_EQ(decoder.read_int32(value, stream), common::E_DECODE_ERR);
    }
}

TEST(RLBECodecTest, RejectsInvalidLongSegmentLength) {
    for (int segment_length : {0, 65}) {
        std::vector<uint8_t> bytes;
        int bit_count = 0;
        append_bits(bytes, bit_count, 1, 32);  // block size
        append_bits(bytes, bit_count, static_cast<uint32_t>(segment_length),
                    7);  // segment length
        bytes.back() <<= (8 - bit_count);

        common::ByteStream stream;
        stream.wrap_from(reinterpret_cast<const char*>(bytes.data()),
                         bytes.size());
        LongRLBEDecoder decoder;
        int64_t value = 0;
        EXPECT_EQ(decoder.read_int64(value, stream), common::E_DECODE_ERR);
    }
}

}  // namespace storage
