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

#ifndef THETA_UNION_EXPERIMENTAL_HPP_
#define THETA_UNION_EXPERIMENTAL_HPP_

#include "serde.hpp"
#include "tuple_sketch.hpp"
#include "theta_union_base.hpp"
#include "theta_sketch_experimental.hpp"

namespace datasketches {

// experimental theta union derived from the same base as tuple union

template<typename Allocator = std::allocator<uint64_t>>
class theta_union_experimental {
public:
  using Entry = uint64_t;
  using ExtractKey = trivial_extract_key;
  using Sketch = theta_sketch_experimental<Allocator>;
  using CompactSketch = compact_theta_sketch_experimental<Allocator>;
  using resize_factor = theta_constants::resize_factor;

  struct pass_through_policy {
    uint64_t operator()(uint64_t internal_entry, uint64_t incoming_entry) const {
      unused(incoming_entry);
      return internal_entry;
    }
  };
  using State = theta_union_base<Entry, ExtractKey, pass_through_policy, Sketch, CompactSketch, Allocator>;

  // No constructor here. Use builder instead.
  class builder;

  /**
   * This method is to update the union with a given sketch
   * @param sketch to update the union with
   */
  void update(const Sketch& sketch);

  /**
   * This method produces a copy of the current state of the union as a compact sketch.
   * @param ordered optional flag to specify if ordered sketch should be produced
   * @return the result of the union
   */
  CompactSketch get_result(bool ordered = true) const;

private:
  State state_;

  // for builder
  theta_union_experimental(uint8_t lg_cur_size, uint8_t lg_nom_size, resize_factor rf, uint64_t theta, uint64_t seed, const Allocator& allocator);
};

template<typename A>
class theta_union_experimental<A>::builder: public theta_base_builder<builder, A> {
public:
  builder(const A& allocator = A());

  /**
   * This is to create an instance of the union with predefined parameters.
   * @return an instance of the union
   */
  theta_union_experimental<A> build() const;
};

} /* namespace datasketches */

#include "theta_union_experimental_impl.hpp"

#endif
