/**
This module provides a `BinaryHeap` (aka priority queue)
adaptor that makes a binary heap out of any user-provided random-access range.

This module is a submodule of $(MREF std, container).

Source: $(PHOBOSSRC std/container/binaryheap.d)

Copyright: 2010- Andrei Alexandrescu. All rights reserved by the respective holders.

License: Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at $(HTTP
boost.org/LICENSE_1_0.txt)).

Authors: $(HTTP erdani.com, Andrei Alexandrescu)
*/
module std.container.binaryheap;

import std.range.primitives;
import std.traits;

public import std.container.util;

///
@system unittest
{
    import std.algorithm.comparison : equal;
    import std.range : take;
    auto maxHeap = heapify([4, 7, 3, 1, 5]);
    assert(maxHeap.take(3).equal([7, 5, 4]));

    auto minHeap = heapify!"a > b"([4, 7, 3, 1, 5]);
    assert(minHeap.take(3).equal([1, 3, 4]));
}

// BinaryHeap
/**
Implements a $(HTTP en.wikipedia.org/wiki/Binary_heap, binary heap)
container on top of a given random-access range type (usually $(D
T[])) or a random-access container type (usually `Array!T`). The
documentation of `BinaryHeap` will refer to the underlying range or
container as the $(I store) of the heap.

The binary heap induces structure over the underlying store such that
accessing the largest element (by using the `front` property) is a
$(BIGOH 1) operation and extracting it (by using the $(D
removeFront()) method) is done fast in $(BIGOH log n) time.

If `less` is the less-than operator, which is the default option,
then `BinaryHeap` defines a so-called max-heap that optimizes
extraction of the $(I largest) elements. To define a min-heap,
instantiate BinaryHeap with $(D "a > b") as its predicate.

Simply extracting elements from a `BinaryHeap` container is
tantamount to lazily fetching elements of `Store` in descending
order. Extracting elements from the `BinaryHeap` to completion
leaves the underlying store sorted in ascending order but, again,
yields elements in descending order.

If `Store` is a range, the `BinaryHeap` cannot grow beyond the
size of that range. If `Store` is a container that supports $(D
insertBack), the `BinaryHeap` may grow by adding elements to the
container.
     */
struct BinaryHeap(Store, alias less = "a < b")
if (isRandomAccessRange!(Store) || isRandomAccessRange!(typeof(Store.init[])))
{
    import std.algorithm.comparison : min;
    import std.algorithm.mutation : move, swapAt;
    import std.algorithm.sorting : HeapOps;
    import std.exception : enforce;
    import std.functional : binaryFun;
    import std.typecons : RefCounted, RefCountedAutoInitialize;

    static if (isRandomAccessRange!Store)
        alias Range = Store;
    else
        alias Range = typeof(Store.init[]);
    alias percolate = HeapOps!(less, Range).percolate;
    alias buildHeap = HeapOps!(less, Range).buildHeap;

// Really weird @@BUG@@: if you comment out the "private:" label below,
// std.algorithm can't unittest anymore
//private:

    // The payload includes the support store and the effective length
    private static struct Data
    {
        Store _store;
        size_t _length;
    }
    // TODO: migrate to use the SafeRefCounted. The problem is that some member
    // functions here become @system with a naive switch.
    private RefCounted!(Data, RefCountedAutoInitialize.no) _payload;
    // Comparison predicate
    private alias comp = binaryFun!(less);
    // Convenience accessors
    private @property ref Store _store()
    {
        assert(_payload.refCountedStore.isInitialized,
                "BinaryHeap not initialized");
        return _payload._store;
    }
    private @property ref size_t _length()
    {
        assert(_payload.refCountedStore.isInitialized,
                "BinaryHeap not initialized");
        return _payload._length;
    }

    // Asserts that the heap property is respected.
    private void assertValid()
    {
        debug
        {
            import std.conv : to;
            if (!_payload.refCountedStore.isInitialized) return;
            if (_length < 2) return;
            for (size_t n = _length - 1; n >= 1; --n)
            {
                auto parentIdx = (n - 1) / 2;
                assert(!comp(_store[parentIdx], _store[n]), to!string(n));
            }
        }
    }

    // @@@BUG@@@: add private here, std.algorithm doesn't unittest anymore
    /*private*/ void pop(Store store)
    {
        assert(!store.empty, "Cannot pop an empty store.");
        if (store.length == 1) return;
        auto t1 = store[].moveFront();
        auto t2 = store[].moveBack();
        store.front = move(t2);
        store.back = move(t1);
        percolate(store[], 0, store.length - 1);
    }

public:

    /**
       Converts the store `s` into a heap. If `initialSize` is
       specified, only the first `initialSize` elements in `s`
       are transformed into a heap, after which the heap can grow up
       to `r.length` (if `Store` is a range) or indefinitely (if
       `Store` is a container with `insertBack`). Performs
       $(BIGOH min(r.length, initialSize)) evaluations of `less`.
     */
    this(Store s, size_t initialSize = size_t.max)
    {
        acquire(s, initialSize);
    }

/**
Takes ownership of a store. After this, manipulating `s` may make
the heap work incorrectly.
     */
    void acquire(Store s, size_t initialSize = size_t.max)
    {
        _payload.refCountedStore.ensureInitialized();
        _store = move(s);
        _length = min(_store.length, initialSize);
        if (_length < 2) return;
        buildHeap(_store[]);
        assertValid();
    }

/**
Takes ownership of a store assuming it already was organized as a
heap.
     */
    void assume(Store s, size_t initialSize = size_t.max)
    {
        _payload.refCountedStore.ensureInitialized();
        _store = s;
        _length = min(_store.length, initialSize);
        assertValid();
    }

/**
Clears the heap. Returns the portion of the store from `0` up to
`length`, which satisfies the $(LINK2 https://en.wikipedia.org/wiki/Heap_(data_structure),
heap property).
     */
    auto release()
    {
        if (!_payload.refCountedStore.isInitialized)
        {
            return typeof(_store[0 .. _length]).init;
        }
        assertValid();
        auto result = _store[0 .. _length];
        _payload = _payload.init;
        return result;
    }

/**
Returns `true` if the heap is _empty, `false` otherwise.
     */
    @property bool empty()
    {
        return !length;
    }

/**
Returns a duplicate of the heap. The `dup` method is available only if the
underlying store supports it.
     */
    static if (is(typeof((Store s) { return s.dup; }(Store.init)) == Store))
    {
        @property BinaryHeap dup()
        {
            BinaryHeap result;
            if (!_payload.refCountedStore.isInitialized) return result;
            result.assume(_store.dup, length);
            return result;
        }
    }

/**
Returns the _length of the heap.
     */
    @property size_t length()
    {
        return _payload.refCountedStore.isInitialized ? _length : 0;
    }

/**
Returns the _capacity of the heap, which is the length of the
underlying store (if the store is a range) or the _capacity of the
underlying store (if the store is a container).
     */
    @property size_t capacity()
    {
        if (!_payload.refCountedStore.isInitialized) return 0;
        static if (is(typeof(_store.capacity) : size_t))
        {
            return _store.capacity;
        }
        else
        {
            return _store.length;
        }
    }

/**
Returns a copy of the _front of the heap, which is the largest element
according to `less`.
     */
    @property ElementType!Store front()
    {
        assert(!empty, "Cannot call front on an empty heap.");
        return _store.front;
    }

/**
Clears the heap by detaching it from the underlying store.
     */
    void clear()
    {
        _payload = _payload.init;
    }

/**
Inserts `value` into the store. If the underlying store is a range
and $(D length == capacity), throws an exception.
     */
    size_t insert(ElementType!Store value)
    {
        static if (is(typeof(_store.insertBack(value))))
        {
            _payload.refCountedStore.ensureInitialized();
            if (length == _store.length)
            {
                // reallocate
                _store.insertBack(value);
            }
            else
            {
                // no reallocation
                _store[_length] = value;
            }
        }
        else
        {
            import std.traits : isDynamicArray;
            static if (isDynamicArray!Store)
            {
                if (length == _store.length)
                    _store.length = (length < 6 ? 8 : length * 3 / 2);
                _store[_length] = value;
            }
            else
            {
                // can't grow
                enforce(length < _store.length,
                        "Cannot grow a heap created over a range");
            }
        }

        // sink down the element
        for (size_t n = _length; n; )
        {
            auto parentIdx = (n - 1) / 2;
            if (!comp(_store[parentIdx], _store[n])) break; // done!
            // must swap and continue
            _store.swapAt(parentIdx, n);
            n = parentIdx;
        }
        ++_length;
        debug(BinaryHeap) assertValid();
        return 1;
    }

/**
Removes the largest element from the heap.
     */
    void removeFront()
    {
        assert(!empty, "Cannot call removeFront on an empty heap.");
        if (_length > 1)
        {
            auto t1 = _store[].moveFront();
            auto t2 = _store[].moveAt(_length - 1);
            _store.front = move(t2);
            _store[_length - 1] = move(t1);
        }
        --_length;
        percolate(_store[], 0, _length);
    }

    /// ditto
    alias popFront = removeFront;

/**
Removes the largest element from the heap and returns a copy of
it. The element still resides in the heap's store. For performance
reasons you may want to use `removeFront` with heaps of objects
that are expensive to copy.
     */
    ElementType!Store removeAny()
    {
        removeFront();
        return _store[_length];
    }

/**
Replaces the largest element in the store with `value`.
     */
    void replaceFront(ElementType!Store value)
    {
        // must replace the top
        assert(!empty, "Cannot call replaceFront on an empty heap.");
        _store.front = value;
        percolate(_store[], 0, _length);
        debug(BinaryHeap) assertValid();
    }

/**
If the heap has room to grow, inserts `value` into the store and
returns `true`. Otherwise, if $(D less(value, front)), calls $(D
replaceFront(value)) and returns again `true`. Otherwise, leaves
the heap unaffected and returns `false`. This method is useful in
scenarios where the smallest `k` elements of a set of candidates
must be collected.
     */
    bool conditionalInsert(ElementType!Store value)
    {
        _payload.refCountedStore.ensureInitialized();
        if (_length < _store.length)
        {
            insert(value);
            return true;
        }

        assert(!_store.empty, "Cannot replace front of an empty heap.");
        if (!comp(value, _store.front)) return false; // value >= largest
        _store.front = value;

        percolate(_store[], 0, _length);
        debug(BinaryHeap) assertValid();
        return true;
    }

/**
Swapping is allowed if the heap is full. If $(D less(value, front)), the
method exchanges store.front and value and returns `true`. Otherwise, it
leaves the heap unaffected and returns `false`.
     */
    bool conditionalSwap(ref ElementType!Store value)
    {
        _payload.refCountedStore.ensureInitialized();
        assert(_length == _store.length,
                "length and number of stored items out of sync");
        assert(!_store.empty, "Cannot swap front of an empty heap.");

        if (!comp(value, _store.front)) return false; // value >= largest

        import std.algorithm.mutation : swap;
        swap(_store.front, value);

        percolate(_store[], 0, _length);
        debug(BinaryHeap) assertValid();

        return true;
    }
}

/// Example from "Introduction to Algorithms" Cormen et al, p 146
@system unittest
{
    import std.algorithm.comparison : equal;
    int[] a = [ 4, 1, 3, 2, 16, 9, 10, 14, 8, 7 ];
    auto h = heapify(a);
    // largest element
    assert(h.front == 16);
    // a has the heap property
    assert(equal(a, [ 16, 14, 10, 8, 7, 9, 3, 2, 4, 1 ]));
}

/// `BinaryHeap` implements the standard input range interface, allowing
/// lazy iteration of the underlying range in descending order.
@system unittest
{
    import std.algorithm.comparison : equal;
    import std.range : take;
    int[] a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7];
    auto top5 = heapify(a).take(5);
    assert(top5.equal([16, 14, 10, 9, 8]));
}

/**
Convenience function that returns a `BinaryHeap!Store` object
initialized with `s` and `initialSize`.
 */
BinaryHeap!(Store, less) heapify(alias less = "a < b", Store)(Store s,
        size_t initialSize = size_t.max)
{

    return BinaryHeap!(Store, less)(s, initialSize);
}

///
@system unittest
{
    import std.conv : to;
    import std.range.primitives;
    {
        // example from "Introduction to Algorithms" Cormen et al., p 146
        int[] a = [ 4, 1, 3, 2, 16, 9, 10, 14, 8, 7 ];
        auto h = heapify(a);
        h = heapify!"a < b"(a);
        assert(h.front == 16);
        assert(a == [ 16, 14, 10, 8, 7, 9, 3, 2, 4, 1 ]);
        auto witness = [ 16, 14, 10, 9, 8, 7, 4, 3, 2, 1 ];
        for (; !h.empty; h.removeFront(), witness.popFront())
        {
            assert(!witness.empty);
            assert(witness.front == h.front);
        }
        assert(witness.empty);
    }
    {
        int[] a = [ 4, 1, 3, 2, 16, 9, 10, 14, 8, 7 ];
        int[] b = new int[a.length];
        BinaryHeap!(int[]) h = BinaryHeap!(int[])(b, 0);
        foreach (e; a)
        {
            h.insert(e);
        }
        assert(b == [ 16, 14, 10, 8, 7, 3, 9, 1, 4, 2 ], to!string(b));
    }
}

@system unittest
{
    // Test range interface.
    import std.algorithm.comparison : equal;
    int[] a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7];
    auto h = heapify(a);
    static assert(isInputRange!(typeof(h)));
    assert(h.equal([16, 14, 10, 9, 8, 7, 4, 3, 2, 1]));
}

// https://issues.dlang.org/show_bug.cgi?id=15675
@system unittest
{
    import std.container.array : Array;

    Array!int elements = [1, 2, 10, 12];
    auto heap = heapify(elements);
    assert(heap.front == 12);
}

// https://issues.dlang.org/show_bug.cgi?id=16072
@system unittest
{
    auto q = heapify!"a > b"([2, 4, 5]);
    q.insert(1);
    q.insert(6);
    assert(q.front == 1);

    // test more multiple grows
    int[] arr;
    auto r = heapify!"a < b"(arr);
    foreach (i; 0 .. 100)
        r.insert(i);

    assert(r.front == 99);
}

@system unittest
{
    import std.algorithm.comparison : equal;
    int[] a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7];
    auto heap = heapify(a);
    auto dup = heap.dup();
    assert(dup.equal([16, 14, 10, 9, 8, 7, 4, 3, 2, 1]));
}

@safe unittest
{
    static struct StructWithoutDup
    {
        int[] a;
        @disable StructWithoutDup dup();
        alias a this;
    }

    // Assert Binary heap can be created when Store doesn't have dup
    // if dup is not used.
    assert(__traits(compiles, ()
        {
            auto s = StructWithoutDup([1,2]);
            auto h = heapify(s);
        }));

    // Assert dup can't be used on BinaryHeaps when Store doesn't have dup
    assert(!__traits(compiles, ()
        {
            auto s = StructWithoutDup([1,2]);
            auto h = heapify(s);
            h.dup();
        }));
}

@safe unittest
{
    static struct StructWithDup
    {
        int[] a;
        StructWithDup dup()
        {
            StructWithDup d;
            return d;
        }
        alias a this;
    }

    // Assert dup can be used on BinaryHeaps when Store has dup
    assert(__traits(compiles, ()
        {
            auto s = StructWithDup([1, 2]);
            auto h = heapify(s);
            h.dup();
        }));
}

@system unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange;

    alias RefRange = DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Random);

    RefRange a;
    RefRange b;
    a.reinit();
    b.reinit();

    auto heap = heapify(a);
    foreach (ref elem; b)
    {
        heap.conditionalSwap(elem);
    }

    assert(equal(heap, [ 5, 5, 4, 4, 3, 3, 2, 2, 1, 1]));
    assert(equal(b, [10, 9, 8, 7, 6, 6, 7, 8, 9, 10]));
}

// https://issues.dlang.org/show_bug.cgi?id=17314
@system unittest
{
    import std.algorithm.comparison : equal;
    int[] a = [5];
    auto heap = heapify(a);
    heap.insert(6);
    assert(equal(heap, [6, 5]));
}

/**
Example for unintuitive behaviour
It is important not to use the Store after a Heap has been instantiated from
it, at least in the cases of Dynamic Arrays. For example, inserting a new element
in a Heap, which is using a Dyamic Array as a Store, will cause a reallocation of
the Store, if the Store is already full. The Heap will not point anymore to the
original Dyamic Array, but point to a new Dynamic Array.
 */

// https://issues.dlang.org/show_bug.cgi?id=18333
@system unittest
{
    import std.stdio;
    import std.algorithm.comparison : equal;
    import std.container.binaryheap;

    int[] a = [ 4, 1, 3, 2, 16, 9, 10, 14, 8, 7 ];
    auto h = heapify(a);

    // Internal representation of Binary Heap tree
    assert(a.equal([16, 14, 10, 8, 7, 9, 3, 2, 4, 1]));

    h.replaceFront(30);
    // Value 16 was replaced by 30
    assert(a.equal([30, 14, 10, 8, 7, 9, 3, 2, 4, 1]));

    // Making changes to the Store will be seen in the Heap
    a[0] = 40;
    assert(h.front() == 40);

    // Inserting a new element will reallocate the Store, leaving
    // the original Store unchanged.
    h.insert(20);
    assert(a.equal([40, 14, 10, 8, 7, 9, 3, 2, 4, 1]));

    // Making changes to the original Store will not affect the Heap anymore
    a[0] = 60;
    assert(h.front() == 40);
}
