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

#include "frequent_items_sketch.hpp"
#include "test_type.hpp"

namespace datasketches {

typedef frequent_items_sketch<test_type, float, test_type_hash, test_type_equal, test_type_serde> frequent_test_type_sketch;

TEST_CASE("frequent items: custom type", "[frequent_items_sketch]") {
  frequent_test_type_sketch sketch(3);
  sketch.update(1, 10); // should survive the purge
  sketch.update(2);
  sketch.update(3);
  sketch.update(4);
  sketch.update(5);
  sketch.update(6);
  sketch.update(7);
  test_type a8(8);
  sketch.update(a8);
  REQUIRE_FALSE(sketch.is_empty());
  REQUIRE(sketch.get_total_weight() == 17);
  REQUIRE(sketch.get_estimate(1) == 10);
  //std::cerr << "num active: " << sketch.get_num_active_items() << std::endl;

  //std::cerr << "get frequent items" << std::endl;
  auto items = sketch.get_frequent_items(frequent_items_error_type::NO_FALSE_POSITIVES);
  REQUIRE(items.size() == 1); // only 1 item should be above threshold
  REQUIRE(items[0].get_item().get_value() == 1);
  REQUIRE(items[0].get_estimate() == 10);

  std::stringstream s(std::ios::in | std::ios::out | std::ios::binary);
  //std::cerr << "serialize" << std::endl;
  sketch.serialize(s);
  //std::cerr << "deserialize" << std::endl;
  auto sketch2 = frequent_test_type_sketch::deserialize(s);
  REQUIRE_FALSE(sketch2.is_empty());
  REQUIRE(sketch2.get_total_weight() == 17);
  REQUIRE(sketch2.get_estimate(1) == 10);
  REQUIRE(sketch.get_num_active_items() == sketch2.get_num_active_items());
  REQUIRE(sketch.get_maximum_error() == sketch2.get_maximum_error());
  //std::cerr << "end" << std::endl;

  std::cout << sketch2.to_string(true);
}

// this is to see the debug print from test_type if enabled there to make sure items are moved
TEST_CASE("frequent items: moving merge", "[frequent_items_sketch]") {
  frequent_test_type_sketch sketch1(3);
  sketch1.update(1);

  frequent_test_type_sketch sketch2(3);
  sketch2.update(2);

  sketch2.merge(std::move(sketch1));
  REQUIRE(sketch2.get_total_weight() == 2);
}

TEST_CASE("frequent items: negative weight", "[frequent_items_sketch]") {
  frequent_test_type_sketch sketch(3);
  REQUIRE_THROWS_AS(sketch.update(1, -1), std::invalid_argument);
}

} /* namespace datasketches */
