// Copyright 2020 The Pigweed 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
//
//     https://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.
#pragma once

#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <type_traits>

#include "pw_assert/assert.h"

namespace pw::containers {

// Define and use a custom Pair object. This is because std::pair does not
// support constexpr assignment until C++20. The assignment is needed since
// the array of pairs will be sorted in the constructor (if not already).
template <typename First, typename Second>
struct Pair {
  First first;
  Second second;

  bool operator==(const Pair& p) const {
    return first == p.first && second == p.second;
  }

  bool operator!=(const Pair& p) const { return !(*this == p); }
};

template <typename T1, typename T2>
Pair(T1, T2) -> Pair<T1, T2>;

// A simple, fixed-size associative array with lookup by key or value.
//
// FlatMaps can be initialized by:
// 1. A std::array of Pair<K, V> objects.
//    FlatMap<char, int, 3> map({{{'A', 1}, {'B', 2}, {'C', 3}}});
//    FlatMap map(std::array{
//        Pair<char, int>{'A', 1},
//        Pair<char, int>{'B', 2},
//        Pair<char, int>{'C', 3},
//    });
// 2. Pair<K, V> objects.
//    FlatMap map = {
//        Pair<char, int>{'A', 1},
//        Pair<char, int>{'B', 2},
//        Pair<char, int>{'C', 3},
//    };
//
// The keys do not need to be sorted as the constructor will sort the items
// if need be.
template <typename Key, typename Value, size_t kArraySize>
class FlatMap {
 public:
  using key_type = Key;
  using mapped_type = Value;
  using value_type = Pair<key_type, mapped_type>;
  using pointer = value_type*;
  using reference = value_type&;
  using size_type = size_t;
  using difference_type = ptrdiff_t;
  using container_type = typename std::array<value_type, kArraySize>;
  using iterator = typename container_type::iterator;
  using const_iterator = typename container_type::const_iterator;

  /// A bidirectional iterator for the mapped values.
  ///
  /// Also an output iterator.
  class mapped_iterator {
   public:
    using value_type = FlatMap::mapped_type;
    using difference_type = std::ptrdiff_t;
    using pointer = value_type*;
    using reference = value_type&;
    using iterator_category = std::bidirectional_iterator_tag;

    constexpr mapped_iterator() : current_{} {}

    constexpr mapped_iterator(const mapped_iterator& other) = default;
    constexpr mapped_iterator& operator=(const mapped_iterator& other) =
        default;

    constexpr reference operator*() const {
      reference value = current_->second;
      return value;
    }

    constexpr pointer operator->() const { return &operator*(); }

    constexpr mapped_iterator& operator++() {
      ++current_;
      return *this;
    }

    constexpr mapped_iterator operator++(int) {
      mapped_iterator original = *this;
      operator++();
      return original;
    }

    constexpr mapped_iterator& operator--() {
      --current_;
      return *this;
    }

    constexpr mapped_iterator operator--(int) {
      mapped_iterator original = *this;
      operator--();
      return original;
    }

    constexpr bool operator==(const mapped_iterator& other) const {
      return current_ == other.current_;
    }

    constexpr bool operator!=(const mapped_iterator& other) const {
      return !(*this == other);
    }

   private:
    friend class FlatMap;

    constexpr mapped_iterator(FlatMap::iterator current) : current_(current) {}

    FlatMap::iterator current_;
  };

  constexpr FlatMap(const std::array<value_type, kArraySize>& items)
      : items_(items) {
    ConstexprSort(items_.begin(), kArraySize);
  }

  // Omits explicit here to support assignment-like syntax, which is common to
  // initialize a container.
  template <typename... Items,
            typename = std::enable_if_t<
                std::conjunction_v<std::is_same<Items, value_type>...>>>
  constexpr FlatMap(const Items&... items) : FlatMap(std::array{items...}) {}

  FlatMap(FlatMap&) = delete;
  FlatMap& operator=(FlatMap&) = delete;

  // Capacity.
  constexpr size_type size() const { return kArraySize; }
  constexpr size_type empty() const { return size() == 0; }
  constexpr size_type max_size() const { return kArraySize; }

  // Lookup.
  /// Accesses a mutable mapped value.
  ///
  /// @pre The key must exist.
  ///
  /// @param[in] key The key to the mapped value.
  ///
  /// @returns A reference to the mapped value.
  constexpr mapped_type& at(const key_type& key) {
    PW_ASSERT(end() != begin());
    iterator it = std::lower_bound(
        items_.begin(), items_.end(), key, IsItemKeyLessThanGivenKey);
    const key_type& found_key = it->first;
    PW_ASSERT(it != items_.end() && found_key == key);
    mapped_type& found_value = it->second;
    return found_value;
  }

  /// Accesses a mapped value.
  ///
  /// @pre The key must exist.
  ///
  /// @param[in] key The key to the mapped value.
  ///
  /// @returns A const reference to the mapped value.
  constexpr const mapped_type& at(const key_type& key) const {
    PW_ASSERT(end() != begin());
    const_iterator it = std::lower_bound(
        items_.cbegin(), items_.cend(), key, IsItemKeyLessThanGivenKey);
    const key_type& found_key = it->first;
    PW_ASSERT(it != items_.cend() && found_key == key);
    const mapped_type& found_value = it->second;
    return found_value;
  }

  constexpr bool contains(const key_type& key) const {
    return find(key) != end();
  }

  constexpr const_iterator find(const key_type& key) const {
    if (end() == begin()) {
      return end();
    }

    const_iterator it = lower_bound(key);
    if (it == end() || it->first != key) {
      return end();
    }
    return it;
  }

  constexpr const_iterator lower_bound(const key_type& key) const {
    return std::lower_bound(begin(), end(), key, IsItemKeyLessThanGivenKey);
  }

  constexpr const_iterator upper_bound(const key_type& key) const {
    return std::upper_bound(
        begin(), end(), key, [](key_type lkey, const value_type& item) {
          return item.first > lkey;
        });
  }

  constexpr std::pair<const_iterator, const_iterator> equal_range(
      const key_type& key) const {
    if (end() == begin()) {
      return std::make_pair(end(), end());
    }

    return std::make_pair(lower_bound(key), upper_bound(key));
  }

  // Iterators.
  constexpr const_iterator begin() const { return cbegin(); }
  constexpr const_iterator cbegin() const { return items_.cbegin(); }
  constexpr const_iterator end() const { return cend(); }
  constexpr const_iterator cend() const { return items_.cend(); }

  /// Gets an iterator to the first mapped value.
  ///
  /// Mapped iterators iterate through the mapped values, and allow mutation of
  /// those values (for a non-const FlatMap object).
  ///
  /// @returns An iterator to the first mapped value.
  constexpr mapped_iterator mapped_begin() {
    return mapped_iterator(items_.begin());
  }

  /// Gets an iterator to one past the last mapped value.
  ///
  /// Mapped iterators iterate through the mapped values, and allow mutation of
  /// those values (for a non-const FlatMap object).
  ///
  /// @returns An iterator to one past the last mapped value.
  constexpr mapped_iterator mapped_end() {
    return mapped_iterator(items_.end());
  }

 private:
  // Simple stable insertion sort function for constexpr support.
  // std::stable_sort is not constexpr. Should not be a problem with performance
  // in regards to the sizes that are typically dealt with.
  static constexpr void ConstexprSort(iterator data, size_type size) {
    if (size < 2) {
      return;
    }

    for (iterator it = data + 1,
                  end = data + static_cast<difference_type>(size);
         it < end;
         ++it) {
      if (it->first < it[-1].first) {
        // Rotate the value into place.
        value_type temp = std::move(*it);
        iterator it2 = it - 1;
        while (true) {
          *(it2 + 1) = std::move(*it2);
          if (it2 == data || !(temp.first < it2[-1].first)) {
            break;
          }
          --it2;
        }
        *it2 = std::move(temp);
      }
    }
  }

  static constexpr bool IsItemKeyLessThanGivenKey(const value_type& item,
                                                  key_type key) {
    const key_type& item_key = item.first;
    return item_key < key;
  }

  std::array<value_type, kArraySize> items_;
};

template <typename K, typename V, typename... Items>
FlatMap(const Pair<K, V>& item1,
        const Items&... items) -> FlatMap<K, V, 1 + sizeof...(items)>;

}  // namespace pw::containers
