// 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_STRINGS_STRING_MEMORY_MAP_H_
#define VERIBLE_COMMON_STRINGS_STRING_MEMORY_MAP_H_

#include <utility>

#include "absl/strings/string_view.h"
#include "common/strings/range.h"
#include "common/util/interval_map.h"
#include "common/util/interval_set.h"
#include "common/util/logging.h"

namespace verible {

namespace internal {
inline std::pair<absl::string_view::const_iterator,
                 absl::string_view::const_iterator>
string_view_to_pair(absl::string_view sv) {
  return std::make_pair(sv.begin(), sv.end());
}
}  // namespace internal

// StringViewSuperRangeMap maps a string_view to a super-range to which it
// belongs.  This can associate a string_view with the full text (file) from
// which it originated.
// Since this operates solely on string_views, it is not responsible for owning
// any of the referenced memory -- the user is responsible for maintaining
// proper string lifetime, owning strings must outlive these objects.
class StringViewSuperRangeMap {
  typedef DisjointIntervalSet<absl::string_view::const_iterator> impl_type;

 public:
  // This iterator dereferences to a std::pair of
  // absl::string_view::const_iterator, which can be constructed into a
  // string_view.
  typedef impl_type::const_iterator const_iterator;

  StringViewSuperRangeMap() = default;

  StringViewSuperRangeMap(const StringViewSuperRangeMap&) = default;
  StringViewSuperRangeMap(StringViewSuperRangeMap&&) = default;
  StringViewSuperRangeMap& operator=(const StringViewSuperRangeMap&) = default;
  StringViewSuperRangeMap& operator=(StringViewSuperRangeMap&&) = default;

  bool empty() const { return string_map_.empty(); }
  const_iterator begin() const { return string_map_.begin(); }
  const_iterator end() const { return string_map_.end(); }

  // Given a substring, return an iterator pointing to the superstring that
  // fully contains the substring, if it exists, else return end().
  const_iterator find(absl::string_view substring) const {
    return string_map_.find({substring.begin(), substring.end()});
  }

  // Similar to find(), but asserts that a superstring range is found,
  // and converts the result directly to a string_view.
  absl::string_view must_find(absl::string_view substring) const {
    const const_iterator found(find(substring));
    CHECK(found != string_map_.end());
    return make_string_view_range(found->first, found->second);  // superstring
  }

  // Insert a superstring (range) that does not overlap with any previously
  // inserted string range.  This is suitable for string ranges that correspond
  // to allocated memory, because allocators only return non-overlapping memory
  // blocks.
  const_iterator must_emplace(absl::string_view superstring) {
    return string_map_.must_emplace(superstring.begin(), superstring.end());
  }

 private:
  // Internal representation of string range map.
  impl_type string_map_;
};

// StringMemoryMap maps (non-owned) string_views to owned memory.
// This class provides a set-like interface to objects of type T.
// T is any type of object that *owns* some string memory, whose
// address range serves as a key.  Since string addresses are the result of
// allocation, they are guaranteed to not overlap.
//   T needs to be move-able, like a std::unique_ptr.
//   Note: std::string is move-able, but *not* guaranteed to maintain the same
//     address after std::move-ing.
// RangeOf is any functor that returns a string_view of memory owned by objects
// of type T.
//
// It is expected that the owned string memory address range never changes over
// the lifetime of objects stored in this map, in other words, RangeOf(obj) will
// always return the same range for the same object.  One way to ensure this is
// to make the underlying storage a 'const std::string'.
//
template <class T, absl::string_view RangeOf(const T&)>
class StringMemoryMap {
  typedef absl::string_view::const_iterator key_type;
  typedef DisjointIntervalMap<key_type, T> map_type;

 public:
  typedef typename map_type::iterator iterator;

  StringMemoryMap() = default;

  StringMemoryMap(const StringMemoryMap&) = delete;
  StringMemoryMap(StringMemoryMap&&) = delete;
  StringMemoryMap& operator=(const StringMemoryMap&) = delete;
  StringMemoryMap& operator=(StringMemoryMap&&) = delete;

  // Returns reference to the object in the set that owns the memory range of
  // string 's', or else nullptr if 's' does not fall entirely within one of the
  // intervals in the map.
  const T* find(absl::string_view sv) const {
    const auto iter = memory_map_.find(internal::string_view_to_pair(sv));
    if (iter == memory_map_.end()) return nullptr;
    return &iter->second;
  }

  // Move-inserts an element into the set, keyed on the memory range owned
  // by the object.
  iterator insert(T&& t) {
    const absl::string_view key = RangeOf(t);
    return memory_map_.must_emplace(internal::string_view_to_pair(key),
                                    std::move(t));
  }

 private:
  map_type memory_map_;
};

}  // namespace verible

#endif  // VERIBLE_COMMON_STRINGS_STRING_MEMORY_MAP_H_
