/*
 * 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 <catch.hpp>

#include <theta_union.hpp>

namespace datasketches {

TEST_CASE("theta union: empty", "[theta_union]") {
  update_theta_sketch sketch1 = update_theta_sketch::builder().build();
  theta_union u = theta_union::builder().build();
  compact_theta_sketch sketch2 = u.get_result();
  REQUIRE(sketch2.get_num_retained() == 0);
  REQUIRE(sketch2.is_empty());
  REQUIRE_FALSE(sketch2.is_estimation_mode());

  u.update(sketch1);
  sketch2 = u.get_result();
  REQUIRE(sketch2.get_num_retained() == 0);
  REQUIRE(sketch2.is_empty());
  REQUIRE_FALSE(sketch2.is_estimation_mode());
}

TEST_CASE("theta union: non empty no retained keys", "[theta_union]") {
  update_theta_sketch update_sketch = update_theta_sketch::builder().set_p(0.001).build();
  update_sketch.update(1);
  theta_union u = theta_union::builder().build();
  u.update(update_sketch);
  compact_theta_sketch sketch = u.get_result();
  REQUIRE(sketch.get_num_retained() == 0);
  REQUIRE_FALSE(sketch.is_empty());
  REQUIRE(sketch.is_estimation_mode());
  REQUIRE(sketch.get_theta() == Approx(0.001).margin(1e-10));
}

TEST_CASE("theta union: exact mode half overlap", "[theta_union]") {
  update_theta_sketch sketch1 = update_theta_sketch::builder().build();
  int value = 0;
  for (int i = 0; i < 1000; i++) sketch1.update(value++);

  update_theta_sketch sketch2 = update_theta_sketch::builder().build();
  value = 500;
  for (int i = 0; i < 1000; i++) sketch2.update(value++);

  theta_union u = theta_union::builder().build();
  u.update(sketch1);
  u.update(sketch2);
  compact_theta_sketch sketch3 = u.get_result();
  REQUIRE_FALSE(sketch3.is_empty());
  REQUIRE_FALSE(sketch3.is_estimation_mode());
  REQUIRE(sketch3.get_estimate() == Approx(1500).margin(1500 * 0.01));
}

TEST_CASE("theta union: estimation mode half overlap", "[theta_union]") {
  update_theta_sketch sketch1 = update_theta_sketch::builder().build();
  int value = 0;
  for (int i = 0; i < 10000; i++) sketch1.update(value++);

  update_theta_sketch sketch2 = update_theta_sketch::builder().build();
  value = 5000;
  for (int i = 0; i < 10000; i++) sketch2.update(value++);

  theta_union u = theta_union::builder().build();
  u.update(sketch1);
  u.update(sketch2);
  compact_theta_sketch sketch3 = u.get_result();
  REQUIRE_FALSE(sketch3.is_empty());
  REQUIRE(sketch3.is_estimation_mode());
  REQUIRE(sketch3.get_estimate() == Approx(15000).margin(15000 * 0.01));
  //std::cerr << sketch3.to_string(true);
}

TEST_CASE("theta union: seed mismatch", "[theta_union]") {
  update_theta_sketch sketch = update_theta_sketch::builder().build();
  sketch.update(1); // non-empty should not be ignored
  theta_union u = theta_union::builder().set_seed(123).build();
  REQUIRE_THROWS_AS(u.update(sketch), std::invalid_argument);
}

} /* namespace datasketches */
