/*
 * 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 <iostream>

#include <catch2/catch.hpp>
#include <tuple_a_not_b.hpp>
#include <theta_sketch.hpp>
#include <stdexcept>

namespace datasketches {

TEST_CASE("tuple a-not-b: empty", "[tuple_a_not_b]") {
  auto a = update_tuple_sketch<float>::builder().build();
  auto b = update_tuple_sketch<float>::builder().build();
  tuple_a_not_b<float> a_not_b;
  auto result = a_not_b.compute(a, b);
  REQUIRE(result.get_num_retained() == 0);
  REQUIRE(result.is_empty());
  REQUIRE_FALSE(result.is_estimation_mode());
  REQUIRE(result.get_estimate() == 0.0);
}

TEST_CASE("tuple a-not-b: non empty no retained keys", "[tuple_a_not_b]") {
  auto a = update_tuple_sketch<float>::builder().build();
  a.update(1, 1.0f);
  auto b = update_tuple_sketch<float>::builder().set_p(0.001f).build();
  tuple_a_not_b<float> a_not_b;

  // B is still empty
  auto result = a_not_b.compute(a, b);
  REQUIRE_FALSE(result.is_empty());
  REQUIRE_FALSE(result.is_estimation_mode());
  REQUIRE(result.get_num_retained() == 1);
  REQUIRE(result.get_theta() == Approx(1).margin(1e-10));
  REQUIRE(result.get_estimate() == 1.0);

  // B is not empty in estimation mode and no entries
  b.update(1, 1.0f);
  REQUIRE(b.get_num_retained() == 0);

  result = a_not_b.compute(a, b);
  REQUIRE_FALSE(result.is_empty());
  REQUIRE(result.is_estimation_mode());
  REQUIRE(result.get_num_retained() == 0);
  REQUIRE(result.get_theta() == Approx(0.001).margin(1e-10));
  REQUIRE(result.get_estimate() == 0.0);
}

TEST_CASE("tuple a-not-b: exact mode half overlap", "[tuple_a_not_b]") {
  auto a = update_tuple_sketch<float>::builder().build();
  int value = 0;
  for (int i = 0; i < 1000; i++) a.update(value++, 1.0f);

  auto b = update_tuple_sketch<float>::builder().build();
  value = 500;
  for (int i = 0; i < 1000; i++) b.update(value++, 1.0f);

  tuple_a_not_b<float> a_not_b;

  // unordered inputs, ordered result
  auto result = a_not_b.compute(a, b);
  REQUIRE_FALSE(result.is_empty());
  REQUIRE_FALSE(result.is_estimation_mode());
  REQUIRE(result.is_ordered());
  REQUIRE(result.get_estimate() == 500.0);

  // unordered inputs, unordered result
  result = a_not_b.compute(a, b, false);
  REQUIRE_FALSE(result.is_empty());
  REQUIRE_FALSE(result.is_estimation_mode());
  REQUIRE_FALSE(result.is_ordered());
  REQUIRE(result.get_estimate() == 500.0);

  // ordered inputs
  result = a_not_b.compute(a.compact(), b.compact());
  REQUIRE_FALSE(result.is_empty());
  REQUIRE_FALSE(result.is_estimation_mode());
  REQUIRE(result.is_ordered());
  REQUIRE(result.get_estimate() == 500.0);

  // A is ordered, so the result is ordered regardless
  result = a_not_b.compute(a.compact(), b, false);
  REQUIRE_FALSE(result.is_empty());
  REQUIRE_FALSE(result.is_estimation_mode());
  REQUIRE(result.is_ordered());
  REQUIRE(result.get_estimate() == 500.0);
}

TEST_CASE("mixed a-not-b: exact mode half overlap", "[tuple_a_not_b]") {
  auto a = update_tuple_sketch<float>::builder().build();
  int value = 0;
  for (int i = 0; i < 1000; i++) a.update(value++, 1.0f);

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

  tuple_a_not_b<float> a_not_b;

  // unordered inputs, ordered result
  auto result = a_not_b.compute(a, compact_tuple_sketch<float>(b, 1, false));
  REQUIRE_FALSE(result.is_empty());
  REQUIRE_FALSE(result.is_estimation_mode());
  REQUIRE(result.is_ordered());
  REQUIRE(result.get_estimate() == 500.0);

  // unordered inputs, unordered result
  result = a_not_b.compute(a, compact_tuple_sketch<float>(b, 1, false), false);
  REQUIRE_FALSE(result.is_empty());
  REQUIRE_FALSE(result.is_estimation_mode());
  REQUIRE_FALSE(result.is_ordered());
  REQUIRE(result.get_estimate() == 500.0);

  // ordered inputs
  result = a_not_b.compute(a.compact(), compact_tuple_sketch<float>(b.compact(), 1));
  REQUIRE_FALSE(result.is_empty());
  REQUIRE_FALSE(result.is_estimation_mode());
  REQUIRE(result.is_ordered());
  REQUIRE(result.get_estimate() == 500.0);

  // A is ordered, so the result is ordered regardless
  result = a_not_b.compute(a.compact(), compact_tuple_sketch<float>(b, 1, false), false);
  REQUIRE_FALSE(result.is_empty());
  REQUIRE_FALSE(result.is_estimation_mode());
  REQUIRE(result.is_ordered());
  REQUIRE(result.get_estimate() == 500.0);
}

TEST_CASE("tuple a-not-b: exact mode disjoint", "[tuple_a_not_b]") {
  auto a = update_tuple_sketch<float>::builder().build();
  int value = 0;
  for (int i = 0; i < 1000; i++) a.update(value++, 1.0f);

  auto b = update_tuple_sketch<float>::builder().build();
  for (int i = 0; i < 1000; i++) b.update(value++, 1.0f);

  tuple_a_not_b<float> a_not_b;

  // unordered inputs
  auto result = a_not_b.compute(a, b);
  REQUIRE_FALSE(result.is_empty());
  REQUIRE_FALSE(result.is_estimation_mode());
  REQUIRE(result.get_estimate() == 1000.0);

  // ordered inputs
  result = a_not_b.compute(a.compact(), b.compact());
  REQUIRE_FALSE(result.is_empty());
  REQUIRE_FALSE(result.is_estimation_mode());
  REQUIRE(result.get_estimate() == 1000.0);
}

TEST_CASE("tuple a-not-b: exact mode full overlap", "[tuple_a_not_b]") {
  auto sketch = update_tuple_sketch<float>::builder().build();
  int value = 0;
  for (int i = 0; i < 1000; i++) sketch.update(value++, 1.0f);

  tuple_a_not_b<float> a_not_b;

  // unordered inputs
  auto result = a_not_b.compute(sketch, sketch);
  REQUIRE(result.is_empty());
  REQUIRE_FALSE(result.is_estimation_mode());
  REQUIRE(result.get_estimate() == 0.0);

  // ordered inputs
  result = a_not_b.compute(sketch.compact(), sketch.compact());
  REQUIRE(result.is_empty());
  REQUIRE_FALSE(result.is_estimation_mode());
  REQUIRE(result.get_estimate() == 0.0);
}

TEST_CASE("tuple a-not-b: estimation mode half overlap", "[tuple_a_not_b]") {
  auto a = update_tuple_sketch<float>::builder().build();
  int value = 0;
  for (int i = 0; i < 10000; i++) a.update(value++, 1.0f);

  auto b = update_tuple_sketch<float>::builder().build();
  value = 5000;
  for (int i = 0; i < 10000; i++) b.update(value++, 1.0f);

  tuple_a_not_b<float> a_not_b;

  // unordered inputs
  auto result = a_not_b.compute(a, b);
  REQUIRE_FALSE(result.is_empty());
  REQUIRE(result.is_estimation_mode());
  REQUIRE(result.get_estimate() == Approx(5000).margin(5000 * 0.02));

  // ordered inputs
  result = a_not_b.compute(a.compact(), b.compact());
  REQUIRE_FALSE(result.is_empty());
  REQUIRE(result.is_estimation_mode());
  REQUIRE(result.get_estimate() == Approx(5000).margin(5000 * 0.02));
}

TEST_CASE("tuple a-not-b: estimation mode disjoint", "[tuple_a_not_b]") {
  auto a = update_tuple_sketch<float>::builder().build();
  int value = 0;
  for (int i = 0; i < 10000; i++) a.update(value++, 1.0f);

  auto b = update_tuple_sketch<float>::builder().build();
  for (int i = 0; i < 10000; i++) b.update(value++, 1.0f);

  tuple_a_not_b<float> a_not_b;

  // unordered inputs
  auto result = a_not_b.compute(a, b);
  REQUIRE_FALSE(result.is_empty());
  REQUIRE(result.is_estimation_mode());
  REQUIRE(result.get_estimate() == Approx(10000).margin(10000 * 0.02));

  // ordered inputs
  result = a_not_b.compute(a.compact(), b.compact());
  REQUIRE_FALSE(result.is_empty());
  REQUIRE(result.is_estimation_mode());
  REQUIRE(result.get_estimate() == Approx(10000).margin(10000 * 0.02));
}

TEST_CASE("tuple a-not-b: estimation mode full overlap", "[tuple_a_not_b]") {
  auto sketch = update_tuple_sketch<float>::builder().build();
  int value = 0;
  for (int i = 0; i < 10000; i++) sketch.update(value++, 1.0f);

  tuple_a_not_b<float> a_not_b;

  // unordered inputs
  auto result = a_not_b.compute(sketch, sketch);
  REQUIRE_FALSE(result.is_empty());
  REQUIRE(result.is_estimation_mode());
  REQUIRE(result.get_estimate() == 0.0);

  // ordered inputs
  result = a_not_b.compute(sketch.compact(), sketch.compact());
  REQUIRE_FALSE(result.is_empty());
  REQUIRE(result.is_estimation_mode());
  REQUIRE(result.get_estimate() == 0.0);
}

TEST_CASE("tuple a-not-b: seed mismatch", "[tuple_a_not_b]") {
  auto sketch = update_tuple_sketch<float>::builder().build();
  sketch.update(1, 1.0f); // non-empty should not be ignored
  tuple_a_not_b<float> a_not_b(123);
  REQUIRE_THROWS_AS(a_not_b.compute(sketch, sketch), std::invalid_argument);
}

TEST_CASE("tuple a-not-b: issue #152", "[tuple_a_not_b]") {
  auto a = update_tuple_sketch<float>::builder().build();
  int value = 0;
  for (int i = 0; i < 10000; i++) a.update(value++, 1.0f);

  auto b = update_tuple_sketch<float>::builder().build();
  value = 5000;
  for (int i = 0; i < 25000; i++) b.update(value++, 1.0f);

  tuple_a_not_b<float> a_not_b;

  // unordered inputs
  auto result = a_not_b.compute(a, b);
  REQUIRE_FALSE(result.is_empty());
  REQUIRE(result.is_estimation_mode());
  REQUIRE(result.get_estimate() == Approx(5000).margin(5000 * 0.03));

  // ordered inputs
  result = a_not_b.compute(a.compact(), b.compact());
  REQUIRE_FALSE(result.is_empty());
  REQUIRE(result.is_estimation_mode());
  REQUIRE(result.get_estimate() == Approx(5000).margin(5000 * 0.03));
}

} /* namespace datasketches */
