/*
 * 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 <catch2/catch.hpp>
#include <fstream>
#include <req_sketch.hpp>

namespace datasketches {

// assume the binary sketches for this test have been generated by datasketches-java code
// in the subdirectory called "java" in the root directory of this project
static std::string testBinaryInputPath = std::string(TEST_BINARY_INPUT_PATH) + "../../java/";

TEST_CASE("req float", "[serde_compat]") {
  const unsigned n_arr[] = {0, 1, 10, 100, 1000, 10000, 100000, 1000000};
  for (const unsigned n: n_arr) {
    std::ifstream is;
    is.exceptions(std::ios::failbit | std::ios::badbit);
    is.open(testBinaryInputPath + "req_float_n" + std::to_string(n) + "_java.sk", std::ios::binary);
    const auto sketch = req_sketch<float>::deserialize(is);
    REQUIRE(sketch.is_HRA());
    REQUIRE(sketch.is_empty() == (n == 0));
    REQUIRE(sketch.is_estimation_mode() == (n > 10));
    REQUIRE(sketch.get_n() == n);
    if (n > 0) {
      REQUIRE(sketch.get_min_item() == 1.0f);
      REQUIRE(sketch.get_max_item() == static_cast<float>(n));
      uint64_t weight = 0;
      for (const auto pair: sketch) {
        REQUIRE(pair.first >= sketch.get_min_item());
        REQUIRE(pair.first <= sketch.get_max_item());
        weight += pair.second;
      }
      REQUIRE(weight == sketch.get_n());
    }
  }
}

} /* namespace datasketches */
