// Copyright 2017-2020 The Verible Authors.
//
// 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 VERIBLE_COMMON_UTIL_TOP_N_H_
#define VERIBLE_COMMON_UTIL_TOP_N_H_

#include <functional>  // for std::greater
#include <queue>       // for std::priority_queue
#include <vector>

namespace verible {

// Maintains a collection of best N elements, as determined by a comparator.
// This class exists as a drop-in replacement for a similar library,
// and provides a subset of the original class's methods and interfaces.
//
// This priority-queue based implementation is NOT optimized;
// its performance does not matter at this time.
template <typename T, typename Comp = std::greater<T>>
class TopN {
 public:
  typedef T value_type;

  explicit TopN(size_t limit) : max_size_(limit) {}

  // Capacity.
  size_t max_size() const { return max_size_; }

  // Current number of elements, always <= max_size().
  size_t size() const { return elements_.size(); }

  bool empty() const { return size() == 0; }

  // TODO(fangism): void reserve(size_t n);

  // Inserts an element in the prescribed sorted order, and caps the size (K).
  // Has same run-time as heap-insertion, no worse than O(lg K) ~ O(1).
  // Removing the worst element is a heap-remove-min-key, which is O(1).
  void push(const value_type& v) {
    elements_.push(v);
    if (size() > max_size()) {
      elements_.pop();  // remove worst element
    }
  }

  // TODO(fangism): bottom(): the next element to fall off the end, if replaced.
  // const value_type& bottom() const;

  // Returns a copy of elements ordered best-to-worst.  (nondestructive)
  std::vector<value_type> Take() const {
    // Copying a priority_queue only to pluck out its elements
    // destructively is inefficient.
    // TODO(fangism): if desired, make a destructive variant that avoids copy
    // TODO(fangism): re-implement using direct heap operations on array
    impl_type copy(elements_);
    // vector(size) constructor requires default constructibility
    std::vector<value_type> result(size());
    auto iter = result.rbegin();  // the first value is the worst, last is best
    while (!copy.empty()) {
      *iter++ = copy.top();
      copy.pop();
    }
    return result;
  }

 private:
  // Maximum number of best elements to retain.
  size_t max_size_;

  // For simplicity, use existing priority_queue internally, which implements
  // the desired ordering.
  typedef std::priority_queue<T, std::vector<T>, Comp> impl_type;

  // Internal storage of elements.
  impl_type elements_;

  // Comparator (same as that used in the elements_ container)
  Comp comp_;
};

}  // namespace verible

#endif  // VERIBLE_COMMON_UTIL_TOP_N_H_
