/*
 * 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 TUPLE_INTERSECTION_HPP_
#define TUPLE_INTERSECTION_HPP_

#include "tuple_sketch.hpp"
#include "theta_intersection_base.hpp"

namespace datasketches {

/*
// for types with defined + operation
template<typename Summary>
struct example_tuple_intersection_policy {
  void operator()(Summary& summary, const Summary& other) const {
    summary += other;
  }
};
*/

/**
 * Tuple intersection.
 * Computes intersection of Tuple sketches.
 */
template<
  typename Summary,
  typename Policy,
  typename Allocator = std::allocator<Summary>
>
class tuple_intersection {
public:
  using Entry = std::pair<uint64_t, Summary>;
  using ExtractKey = pair_extract_key<uint64_t, Summary>;
  using Sketch = tuple_sketch<Summary, Allocator>;
  using CompactSketch = compact_tuple_sketch<Summary, Allocator>;
  using AllocEntry = typename std::allocator_traits<Allocator>::template rebind_alloc<Entry>;

  // reformulate the external policy that operates on Summary
  // in terms of operations on Entry
  struct internal_policy {
    internal_policy(const Policy& external_policy): external_policy_(external_policy) {}
    void operator()(Entry& internal_entry, const Entry& incoming_entry) const {
      external_policy_(internal_entry.second, incoming_entry.second);
    }
    void operator()(Entry& internal_entry, Entry&& incoming_entry) const {
      external_policy_(internal_entry.second, std::move(incoming_entry.second));
    }
    const Policy& get_external_policy() const { return external_policy_; }
    Policy external_policy_;
  };

  using State = theta_intersection_base<Entry, ExtractKey, internal_policy, Sketch, CompactSketch, AllocEntry>;

  /**
   * Constructor
   * @param seed for the hash function that was used to create the sketch
   * @param policy user-defined way of combining Summary during intersection
   * @param allocator to use for allocating and deallocating memory
   */
  explicit tuple_intersection(uint64_t seed = DEFAULT_SEED, const Policy& policy = Policy(), const Allocator& allocator = Allocator());

  /**
   * Updates the intersection with a given sketch.
   * The intersection can be viewed as starting from the "universe" set, and every update
   * can reduce the current set to leave the overlapping subset only.
   * @param sketch represents input set for the intersection
   */
  template<typename FwdSketch>
  void update(FwdSketch&& sketch);

  /**
   * Produces a copy of the current state of the intersection.
   * If update() was not called, the state is the infinite "universe",
   * which is considered an undefined state, and throws an exception.
   * @param ordered optional flag to specify if an ordered sketch should be produced
   * @return the result of the intersection
   */
  CompactSketch get_result(bool ordered = true) const;

  /**
   * Returns true if the state of the intersection is defined (not infinite "universe").
   * @return true if the state is valid
   */
  bool has_result() const;

protected:
  State state_;
};

} /* namespace datasketches */

#include "tuple_intersection_impl.hpp"

#endif
