/**
 *   Copyright 2011-2015 Quickstep Technologies LLC.
 *   Copyright 2015 Pivotal Software, Inc.
 *   Copyright 2016, Quickstep Research Group, Computer Sciences Department,
 *     University of Wisconsin—Madison.
 *
 *   Licensed 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 QUICKSTEP_EXPRESSIONS_AGGREGATION_AGGREGATION_HANDLE_COUNT_HPP_
#define QUICKSTEP_EXPRESSIONS_AGGREGATION_AGGREGATION_HANDLE_COUNT_HPP_

#include <atomic>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <vector>

#include "catalog/CatalogTypedefs.hpp"
#include "expressions/aggregation/AggregationConcreteHandle.hpp"
#include "expressions/aggregation/AggregationHandle.hpp"
#include "storage/HashTableBase.hpp"
#include "types/TypedValue.hpp"
#include "utility/Macros.hpp"

namespace quickstep {

class ColumnVector;
class StorageManager;
class Type;
class ValueAccessor;

template <bool, bool> class AggregationHandleCount;

/** \addtogroup Expressions
 *  @{
 */

/**
 * @brief Aggregation state of count.
 */
class AggregationStateCount : public AggregationState {
 public:
  /**
   * @brief Copy constructor.
   */
  AggregationStateCount(const AggregationStateCount &state)
      : count_(state.count_.load(std::memory_order_relaxed)) {}

  /**
   * @brief Destructor.
   */
  ~AggregationStateCount() override {}

 private:
  friend class AggregationHandleCount<false, false>;
  friend class AggregationHandleCount<false, true>;
  friend class AggregationHandleCount<true, false>;
  friend class AggregationHandleCount<true, true>;

  AggregationStateCount()
      : count_(0) {
  }

  explicit AggregationStateCount(const std::int64_t initial_count)
      : count_(initial_count) {
  }

  std::atomic<std::int64_t> count_;
};

/**
 * @brief An aggregationhandle for count.
 *
 * @param count_star If true, this AggregationHandleCount is for nullary
 *        COUNT(*). If false, it is a COUNT over some scalar expression.
 * @param nullable_type If true, the argument to COUNT() is nullable, and NULL
 *        values should not be included in the count. If false, the argument is
 *        not nullable and NULL-checks can safely be skipped.
 **/
template <bool count_star, bool nullable_type>
class AggregationHandleCount : public AggregationConcreteHandle {
 public:
  ~AggregationHandleCount() override {
  }

  AggregationState* createInitialState() const override {
    return new AggregationStateCount();
  }

  AggregationStateHashTableBase* createGroupByHashTable(
      const HashTableImplType hash_table_impl,
      const std::vector<const Type*> &group_by_types,
      const std::size_t estimated_num_groups,
      StorageManager *storage_manager) const override;

  inline void iterateNullaryInl(AggregationStateCount *state) const {
    state->count_.fetch_add(1, std::memory_order_relaxed);
  }

  /**
   * @brief Iterate with count aggregation state.
   */
  inline void iterateUnaryInl(AggregationStateCount *state, const TypedValue &value) const {
    if ((!nullable_type) || (!value.isNull())) {
      state->count_.fetch_add(1, std::memory_order_relaxed);
    }
  }

  AggregationState* accumulateNullary(const std::size_t num_tuples) const override {
    return new AggregationStateCount(num_tuples);
  }

  AggregationState* accumulateColumnVectors(
      const std::vector<std::unique_ptr<ColumnVector>> &column_vectors) const override;

#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
  AggregationState* accumulateValueAccessor(
      ValueAccessor *accessor,
      const std::vector<attribute_id> &accessor_id) const override;
#endif

  void aggregateValueAccessorIntoHashTable(
      ValueAccessor *accessor,
      const std::vector<attribute_id> &argument_ids,
      const std::vector<attribute_id> &group_by_key_ids,
      AggregationStateHashTableBase *hash_table) const override;

  void mergeStates(const AggregationState &source,
                   AggregationState *destination) const override;

  TypedValue finalize(const AggregationState &state) const override {
    return TypedValue(static_cast<const AggregationStateCount&>(state).count_.load(std::memory_order_relaxed));
  }

  inline TypedValue finalizeHashTableEntry(const AggregationState &state) const {
    return TypedValue(static_cast<const AggregationStateCount&>(state).count_.load(std::memory_order_relaxed));
  }

  ColumnVector* finalizeHashTable(
      const AggregationStateHashTableBase &hash_table,
      std::vector<std::vector<TypedValue>> *group_by_keys) const override;

  /**
   * @brief Implementation of AggregationHandle::aggregateOnDistinctifyHashTableForSingle()
   *        for SUM aggregation.
   */
  AggregationState* aggregateOnDistinctifyHashTableForSingle(
      const AggregationStateHashTableBase &distinctify_hash_table) const override;

  /**
   * @brief Implementation of AggregationHandle::aggregateOnDistinctifyHashTableForGroupBy()
   *        for SUM aggregation.
   */
  void aggregateOnDistinctifyHashTableForGroupBy(
      const AggregationStateHashTableBase &distinctify_hash_table,
      AggregationStateHashTableBase *aggregation_hash_table) const override;

 private:
  friend class AggregateFunctionCount;

  /**
   * @brief Constructor.
   **/
  AggregationHandleCount() {
  }

  DISALLOW_COPY_AND_ASSIGN(AggregationHandleCount);
};

/** @} */

}  // namespace quickstep

#endif  // QUICKSTEP_EXPRESSIONS_AGGREGATION_AGGREGATION_HANDLE_COUNT__
