#!/bin/sh
set -e

testdir=$(mktemp -d)
trap 'rm -rf "$testdir"' EXIT

mkdir -p "$testdir/use-rapidarchive"
cat > "$testdir/use-rapidarchive/CMakeLists.txt" <<'EOF'
cmake_minimum_required(VERSION 3.10)
project(use-rapidarchive CXX)
find_package(rapidarchive REQUIRED)
add_executable(test-rapidarchive main.cpp)
target_link_libraries(test-rapidarchive PRIVATE rapidarchive)
target_compile_features(test-rapidarchive PRIVATE cxx_std_17)
EOF

cat > "$testdir/use-rapidarchive/main.cpp" <<'EOF'
#include <cassert>
#include <cstdint>
#include <fstream>
#include <string>
#include <vector>

#include <array>

#include <zlib.h>

#include <rapidgzip/gzip/GzipReader.hpp>

int main()
{
    std::string data;
    for (int i = 0; i < 10000; ++i) {
        data += "librapidarchive autopkgtest line " + std::to_string(i) + "\n";
    }

    // Create a gzip file with zlib
    const auto bound = compressBound(data.size());
    std::vector<Bytef> compressed(bound);
    z_stream stream{};
    stream.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data.data()));
    stream.avail_in = static_cast<uInt>(data.size());
    stream.next_out = compressed.data();
    stream.avail_out = static_cast<uInt>(compressed.size());
    assert(deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8,
                        Z_DEFAULT_STRATEGY) == Z_OK);
    assert(deflate(&stream, Z_FINISH) == Z_STREAM_END);
    compressed.resize(stream.total_out);
    deflateEnd(&stream);

    const char* path = "/tmp/rapidarchive-autopkgtest.gz";
    {
        std::ofstream out(path, std::ios::binary);
        out.write(reinterpret_cast<const char*>(compressed.data()),
                  static_cast<std::streamsize>(compressed.size()));
    }

    // Decompress with rapidarchive. GzipReader takes a UniqueFileReader; the
    // path-based constructor is only compiled with WITH_PYTHON_SUPPORT.
    rapidgzip::GzipReader reader(
        std::make_unique<rapidgzip::StandardFileReader>(std::string(path)) );

    // GzipReader::size() is only valid once the stream has been read, so read
    // it incrementally in chunks until EOF.
    std::vector<char> result;
    std::array<char, 65536> buffer;
    while (true) {
        const auto nBytesRead = reader.read(buffer.data(), buffer.size());
        if (nBytesRead == 0) {
            break;
        }
        result.insert(result.end(), buffer.begin(), buffer.begin() + nBytesRead);
    }

    assert(std::string(result.begin(), result.end()) == data);

    std::remove(path);
    return 0;
}
EOF

(
    cd "$testdir/use-rapidarchive"
    cmake -B build .
    cmake --build build
    ./build/test-rapidarchive
)

echo "OK"
