#ifndef VTR_LINEAR_MAP_H
#define VTR_LINEAR_MAP_H
#include <vector>
#include <stdexcept>

#include "vtr_sentinels.h"

namespace vtr {

//A std::map-like container which is indexed by K
//
//The main use of this container is to behave like a std::map which is optimized to hold
//mappings between a dense linear range of keys (e.g. vtr::StrongId).
//
//Requires that K be convertable to size_t with the size_t operator (i.e. size_t()), and
//that the conversion results in a linearly increasing index into the underlying vector.
//Also requires that K() return the sentinel value used to mark invalid entries.
//
//If you only need to access the value associated with the key consider using vtr::vector_map
//instead, which provides a similar but more std::vector-like interface.
//
//Note that it is possible to use linear_map with sparse/non-contiguous keys, but this is typically
//memory inefficient as the underlying vector will allocate space for [0..size_t(max_key)-1],
//where max_key is the largest key that has been inserted.
//
//As with a std::vector, it is the caller's responsibility to ensure there is sufficient space 
//when a given index/key before it is accessed. The exception to this are the find() and insert() 
//methods which handle non-existing keys gracefully.
template<class K, class T, class Sentinel=DefaultSentinel<K>>
class linear_map {
    public:
        typedef K key_type;
        typedef T mapped_type;
        typedef std::pair<K,T> value_type;
        typedef value_type& reference;
        typedef const value_type& const_reference;
        typedef typename std::vector<value_type>::iterator iterator;
        typedef typename std::vector<value_type>::const_iterator const_iterator;
        typedef typename std::vector<value_type>::reverse_iterator reverse_iterator;
        typedef typename std::vector<value_type>::const_reverse_iterator const_reverse_iterator;
        typedef typename std::vector<value_type>::difference_type difference_type;
        typedef typename std::vector<value_type>::size_type size_type;

    public:
        //Standard big 5
        linear_map() = default;
        linear_map(const linear_map&) = default;
        linear_map(linear_map&&) = default;
        linear_map& operator=(const linear_map&) = default;
        linear_map& operator=(linear_map&&) = default;

        linear_map(size_t num_keys)
            : vec_(num_keys, std::make_pair(sentinel(), T())) //Initialize all with sentinel values
            {}

        iterator                begin()             { return vec_.begin(); }
        const_iterator          begin()     const   { return vec_.begin(); }
        iterator                end()               { return vec_.end(); }
        const_iterator          end()       const   { return vec_.end(); }
        reverse_iterator        rbegin()            { return vec_.rbegin(); }
        const_reverse_iterator  rbegin()    const   { return vec_.rbegin(); }
        reverse_iterator        rend()              { return vec_.rend(); }
        const_reverse_iterator  rend()      const   { return vec_.rend(); }
        const_iterator          cbegin()    const   { return vec_.begin(); }
        const_iterator          cend()      const   { return vec_.end(); }
        const_reverse_iterator  crbegin()   const   { return vec_.rbegin(); }
        const_reverse_iterator  crend()     const   { return vec_.rend(); }

        bool empty() const { return vec_.empty(); }
        size_type size() const { return vec_.size(); }
        size_type max_size() const { return vec_.max_size(); }

        mapped_type& operator[](const key_type& key) {
            auto iter = find(key);
            if(iter == end()) {
                //Not found, create it
                iter = insert(std::make_pair(key,mapped_type())).first;
            }

            return iter->second;
        }

        mapped_type& at(const key_type& key) {
            return const_cast<mapped_type&>(const_cast<const linear_map*>(this)->at(key));
        }

        const mapped_type& at(const key_type& key) const {
            auto iter = find(key);
            if(iter == end()) {
                throw std::out_of_range("Invalid key");
            }
            return iter->second;
        }

        //Insert value
        std::pair<iterator,bool> insert(const value_type& value) {
            auto iter = find(value.first);
            if(iter != end()) {
                //Found existing
                return std::make_pair(iter, false);
            } else {
                //Insert
                size_t index = size_t(value.first);

                if(index >= vec_.size()) {
                    //Make space, initialize empty slots with sentinel values
                    vec_.resize(index + 1, std::make_pair(sentinel(), T()));
                }

                vec_[index] = value;

                return std::make_pair(vec_.begin() + index, true);
            }
        }

        //Insert range
        template<class InputIterator>
        void insert(InputIterator first, InputIterator last) {
            for(InputIterator iter = first; iter != last; ++iter) {
                insert(*iter);
            }
        }

        //Erase by key
        void erase(const key_type& key) {
            auto iter = find(key);
            if(iter != end()) {
                erase(iter);
            }
        }

        //Erase at iterator
        void erase(const_iterator position) {
            iterator pos = convert_to_iterator(position);
            pos->first = sentinel(); //Mark invalid
        }

        //Erase range
        void erase(const_iterator first, const_iterator last) {
            for(auto iter = first; iter != last; ++iter) {
                erase(iter);
            }
        }

        void swap(linear_map& other) { std::swap(vec_, other.vec_); }

        void clear() { vec_.clear(); }

        template<class ...Args>
        std::pair<iterator,bool> emplace(const key_type& key, Args&&... args) {
            auto iter = find(key);
            if(iter != end()) {
                //Found
                return std::make_pair(iter, false);
            } else {
                //Emplace
                size_t index = size_t(key);

                if(index >= vec_.size()) {
                    //Make space, initialize empty slots with sentinel values
                    vec_.resize(index + 1, value_type(sentinel(), T()));
                }

                vec_[index] = value_type(key, std::forward<Args>(args)...);

                return std::make_pair(vec_.begin() + index, true);
            }
        }

        void reserve(size_type n) { vec_.reserve(n); }
        void shrink_to_fit() { vec_.shrink_to_fit(); }

        iterator find(const key_type& key) {
            const_iterator const_iter = const_cast<const linear_map*>(this)->find(key);
            return convert_to_iterator(const_iter);
        }

        const_iterator find(const key_type& key) const {
            size_t index = size_t(key);

            if(index < vec_.size() && vec_[index].first != sentinel()) {
                return vec_.begin() + index;
            }
            return end();
        }

        size_type count(const key_type& key) const {
            return (find(key) == end()) ? 0 : 1;
        }

        iterator lower_bound(const key_type& key) {
            const_iterator const_iter = const_cast<const linear_map*>(this)->lower_bound(key); 
            return convert_to_iterator(const_iter);
        }

        const_iterator lower_bound(const key_type& key) const {
            return find(key); 
        }

        iterator upper_bound(const key_type& key) {
            const_iterator const_iter = const_cast<const linear_map*>(this)->upper_bound(key); 
            return convert_to_iterator(const_iter);
        }

        const_iterator upper_bound(const key_type& key) const {
            auto iter = find(key);
            return (iter != end()) ? iter + 1 : end();
        }

        std::pair<iterator,iterator> equal_range(const key_type& key) {
            auto const_iter_pair = const_cast<const linear_map*>(this)->equal_range(key);
            return std::pair<iterator,iterator>(iterator(const_iter_pair.first), iterator(const_iter_pair.second));
        }

        std::pair<const_iterator,const_iterator> equal_range(const key_type& key) const {
            auto lb_iter = lower_bound(key);
            auto ub_iter = upper_bound(key);
            return (lb_iter != end()) ? std::make_pair(lb_iter, ub_iter) : std::make_pair(ub_iter, ub_iter);
        }

        size_type valid_size() const {
            size_t valid_cnt = 0;
            for(const auto& kv : vec_) {
                if(kv.first != sentinel()) {
                    ++valid_cnt;
                }
            }
            return valid_cnt;
        }

    public:
        friend void swap(linear_map& lhs, linear_map& rhs) { 
            std::swap(lhs.vec_, rhs.vec_); 
        }

    private:
        iterator convert_to_iterator(const_iterator const_iter) {
            //This is a work around for the fact that there is no conversion between
            //a const_iterator and iterator.
            //
            //We intiailize i to the start of the container and then advance it by
            //the distance to const_iter. The resulting i points to the same element
            //as const_iter
            //
            //Note that to be able to call std::distance with an iterator and
            //const_iterator we need to specify the type as const_iterator (relying
            //on the implicit conversion from iterator to const_iterator for i)
            //
            //Since the iterators are really vector (i.e. random-access) iterators
            //both distance and advance take constant time
            iterator i = begin();
            std::advance(i, std::distance<const_iterator>(i, const_iter));
            return i;
        }

        constexpr K sentinel() const { return Sentinel::INVALID(); }

    private:
        std::vector<value_type> vec_;
};

} //namespace
#endif
