// 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.

#include "common/util/interval_map.h"

#include <memory>
#include <string>
#include <tuple>
#include <vector>

#include "absl/strings/string_view.h"
#include "common/util/range.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace verible {
namespace {

typedef DisjointIntervalMap<int, std::unique_ptr<int>> IntIntervalMap;
typedef DisjointIntervalMap<int, std::unique_ptr<std::string>>
    StringIntervalMap;

TEST(DisjointIntervalMapTest, DefaultCtor) {
  const IntIntervalMap imap;
  EXPECT_TRUE(imap.empty());
}

TEST(DisjointIntervalMapTest, FindEmpty) {
  const IntIntervalMap imap;
  EXPECT_EQ(imap.find(3), imap.end());
}

TEST(DisjointIntervalMapTest, EmplaceOne) {
  IntIntervalMap imap;
  const auto p = imap.emplace({3, 4}, std::make_unique<int>(5));
  EXPECT_TRUE(p.second);
  EXPECT_EQ(p.first->first, std::make_pair(3, 4));
  EXPECT_EQ(*p.first->second, 5);
  EXPECT_FALSE(imap.empty());
}

TEST(DisjointIntervalMapTest, EmplaceOneEnsureMove) {
  StringIntervalMap imap;
  auto s = std::make_unique<std::string>("Gruetzi!");
  const absl::string_view sv(*s);
  const auto p = imap.emplace({3, 7}, std::move(s));
  EXPECT_TRUE(p.second);
  EXPECT_EQ(p.first->first, std::make_pair(3, 7));
  // ownership transferred, string_view range is still valid
  const absl::string_view new_sv(*p.first->second);
  EXPECT_TRUE(BoundsEqual(new_sv, sv)) << "got: " << new_sv << " vs. " << sv;
}

TEST(DisjointIntervalMapTest, EmplaceNonoverlappingAbutting) {
  IntIntervalMap imap;
  {
    const auto p = imap.emplace({3, 4}, std::make_unique<int>(5));
    EXPECT_TRUE(p.second);
  }
  {
    // insert new leftmost range
    const auto p = imap.emplace({1, 3}, std::make_unique<int>(9));
    EXPECT_TRUE(p.second);
  }
  {
    // insert new rightmost range
    const auto p = imap.emplace({4, 7}, std::make_unique<int>(2));
    EXPECT_TRUE(p.second);
  }

  EXPECT_EQ(imap.find(0), imap.end());
  for (int i = 1; i < 3; ++i) {
    const auto f = imap.find(i);
    ASSERT_NE(f, imap.end());
    EXPECT_EQ(*f->second, 9);
  }
  for (int i = 3; i < 4; ++i) {
    const auto f = imap.find(i);
    ASSERT_NE(f, imap.end());
    EXPECT_EQ(*f->second, 5);
  }
  for (int i = 4; i < 7; ++i) {
    const auto f = imap.find(i);
    ASSERT_NE(f, imap.end());
    EXPECT_EQ(*f->second, 2);
  }
  EXPECT_EQ(imap.find(7), imap.end());
}

TEST(DisjointIntervalMapTest, EmplaceNonoverlappingWithGaps) {
  IntIntervalMap imap;
  {
    const auto p = imap.emplace({20, 25}, std::make_unique<int>(4));
    EXPECT_TRUE(p.second);
  }
  {
    // insert new rightmost range
    const auto p = imap.emplace({30, 40}, std::make_unique<int>(2));
    EXPECT_TRUE(p.second);
  }
  {
    // insert new leftmost range
    const auto p = imap.emplace({10, 15}, std::make_unique<int>(8));
    EXPECT_TRUE(p.second);
  }

  for (int i = 0; i < 10; ++i) {
    EXPECT_EQ(imap.find(i), imap.end());
  }
  for (int i = 10; i < 15; ++i) {
    const auto f = imap.find(i);
    ASSERT_NE(f, imap.end());
    EXPECT_EQ(*f->second, 8);
  }
  for (int i = 15; i < 20; ++i) {
    EXPECT_EQ(imap.find(i), imap.end());
  }
  for (int i = 20; i < 25; ++i) {
    const auto f = imap.find(i);
    ASSERT_NE(f, imap.end());
    EXPECT_EQ(*f->second, 4);
  }
  for (int i = 25; i < 30; ++i) {
    EXPECT_EQ(imap.find(i), imap.end());
  }
  for (int i = 30; i < 40; ++i) {
    const auto f = imap.find(i);
    ASSERT_NE(f, imap.end());
    EXPECT_EQ(*f->second, 2);
  }
  EXPECT_EQ(imap.find(40), imap.end());

  {
    // fill a gap completely
    const auto p = imap.emplace({15, 20}, std::make_unique<int>(77));
    EXPECT_TRUE(p.second);
    EXPECT_EQ(*imap.find(14)->second, 8);
    for (int i = 15; i < 20; ++i) {
      const auto f = imap.find(i);
      ASSERT_NE(f, imap.end());
      EXPECT_EQ(*f->second, 77);
    }
    EXPECT_EQ(*imap.find(20)->second, 4);
  }

  {
    // fill a gap partially
    const auto p = imap.emplace({27, 29}, std::make_unique<int>(44));
    EXPECT_TRUE(p.second);
    for (int i = 25; i < 27; ++i) {
      EXPECT_EQ(imap.find(i), imap.end());
    }
    for (int i = 27; i < 29; ++i) {
      const auto f = imap.find(i);
      ASSERT_NE(f, imap.end());
      EXPECT_EQ(*f->second, 44);
    }
    for (int i = 29; i < 30; ++i) {
      EXPECT_EQ(imap.find(i), imap.end());
    }
  }
}

TEST(DisjointIntervalMapTest, EmplaceBackwardsRange) {
  IntIntervalMap imap;
  EXPECT_DEATH(imap.emplace({4, 3}, std::make_unique<int>(5)), "");
}

TEST(DisjointIntervalMapTest, MustEmplaceSuccess) {
  IntIntervalMap imap;
  constexpr std::tuple<int, int, int> kTestValues[] = {
      {3, 4, 5}, {1, 3, 9}, {4, 7, 2}, {-10, -5, 0}, {10, 15, 33},
  };
  for (const auto& t : kTestValues) {
    const auto iter = imap.must_emplace({std::get<0>(t), std::get<1>(t)},
                                        std::make_unique<int>(std::get<2>(t)));
    // Ensure that inserted value is the expected key and value.
    EXPECT_EQ(iter->first.first, std::get<0>(t));
    EXPECT_EQ(iter->first.second, std::get<1>(t));
    EXPECT_EQ(*iter->second, std::get<2>(t));
  }
}

TEST(DisjointIntervalMapTest, MustEmplaceOverlapLeft) {
  IntIntervalMap imap;
  imap.must_emplace({30, 40}, std::make_unique<int>(5));
  EXPECT_DEATH(imap.must_emplace({20, 31}, std::make_unique<int>(9)),
               "Failed to emplace");
}

TEST(DisjointIntervalMapTest, MustEmplaceOverlapRight) {
  IntIntervalMap imap;
  imap.must_emplace({30, 40}, std::make_unique<int>(5));
  EXPECT_DEATH(imap.must_emplace({39, 45}, std::make_unique<int>(22)),
               "Failed to emplace");
}

TEST(DisjointIntervalMapTest, MustEmplaceOverlapInterior) {
  IntIntervalMap imap;
  imap.must_emplace({30, 40}, std::make_unique<int>(5));
  EXPECT_DEATH(imap.must_emplace({31, 39}, std::make_unique<int>(12)),
               "Failed to emplace");
}

TEST(DisjointIntervalMapTest, MustEmplaceOverlapEnveloped) {
  IntIntervalMap imap;
  imap.must_emplace({30, 40}, std::make_unique<int>(5));
  EXPECT_DEATH(imap.must_emplace({29, 40}, std::make_unique<int>(29)),
               "Failed to emplace");
}

TEST(DisjointIntervalMapTest, MustEmplaceSpanningTwo) {
  IntIntervalMap imap;
  imap.must_emplace({30, 40}, std::make_unique<int>(5));
  imap.must_emplace({50, 60}, std::make_unique<int>(5));
  EXPECT_DEATH(imap.must_emplace({35, 55}, std::make_unique<int>(99)),
               "Failed to emplace");
}

TEST(DisjointIntervalMapTest, MustEmplaceOverlapsLower) {
  IntIntervalMap imap;
  imap.must_emplace({30, 40}, std::make_unique<int>(5));
  imap.must_emplace({50, 60}, std::make_unique<int>(5));
  EXPECT_DEATH(imap.must_emplace({35, 45}, std::make_unique<int>(55)),
               "Failed to emplace");
}

TEST(DisjointIntervalMapTest, MustEmplaceOverlapsUpper) {
  IntIntervalMap imap;
  imap.must_emplace({30, 40}, std::make_unique<int>(5));
  imap.must_emplace({50, 60}, std::make_unique<int>(5));
  EXPECT_DEATH(imap.must_emplace({45, 55}, std::make_unique<int>(66)),
               "Failed to emplace");
}

TEST(DisjointIntervalMapTest, FindInterval) {
  IntIntervalMap imap;
  imap.must_emplace({20, 25}, std::make_unique<int>(1));
  for (int i = 19; i < 26; ++i) {
    for (int j = i + 1; j < 26; ++j) {
      const auto found = imap.find({i, j});
      if (i >= 20 && j <= 25) {
        ASSERT_NE(found, imap.end());
        EXPECT_EQ(found->first.first, 20);
        EXPECT_EQ(found->first.second, 25);
        EXPECT_EQ(*found->second, 1);
      } else {
        EXPECT_EQ(found, imap.end());
      }
    }
  }
}

TEST(DisjointIntervalMapTest, BeginEndRangeConstIterators) {
  IntIntervalMap imap;
  // values chosen to be == interval size
  imap.must_emplace({50, 60}, std::make_unique<int>(10));
  imap.must_emplace({30, 35}, std::make_unique<int>(5));
  imap.must_emplace({39, 46}, std::make_unique<int>(7));
  for (const auto& pair : imap) {
    EXPECT_EQ(pair.first.second - pair.first.first, *pair.second);
  }
}

// std::vector is moveable and guaranteed to transfer ownership over its
// internal array, i.e. no small/inline-vector optimization.
typedef DisjointIntervalMap<std::vector<int>::const_iterator, std::vector<int>>
    VectorIntervalMap;

static VectorIntervalMap::iterator AllocateVectorBlock(VectorIntervalMap* vmap,
                                                       int min, int max) {
  std::vector<int> v(max - min);
  int i = min;
  for (auto& e : v) {
    e = i;
    ++i;
  }
  // Caution: do not reference v and move(v) in the same set of call parameters
  // [sequence-point].
  const auto key(std::make_pair(v.cbegin(), v.cend()));
  const auto new_iter = vmap->must_emplace(key, std::move(v));
  EXPECT_EQ(new_iter->first, key);
  return new_iter;
}

static void VerifyVectorBlock(const VectorIntervalMap& vmap,
                              VectorIntervalMap::const_iterator block) {
  for (auto left = block->first.first; left != std::prev(block->first.second);
       ++left) {
    // Verify scalar find.
    EXPECT_TRUE(vmap.find(left) == block);
    // Verify range find.
    for (auto right = std::next(left); right != block->first.second; ++right) {
      EXPECT_TRUE(vmap.find({left, right}) == block);
    }
  }
}

TEST(DisjointIntervalMapTest, VectorDemo) {
  VectorIntervalMap vmap;
  const auto block1 = AllocateVectorBlock(&vmap, 10, 20);
  VerifyVectorBlock(vmap, block1);

  const auto block2 = AllocateVectorBlock(&vmap, 30, 40);
  VerifyVectorBlock(vmap, block1);
  VerifyVectorBlock(vmap, block2);

  const auto block3 = AllocateVectorBlock(&vmap, 20, 30);
  VerifyVectorBlock(vmap, block1);
  VerifyVectorBlock(vmap, block2);
  VerifyVectorBlock(vmap, block3);
}

}  // namespace
}  // namespace verible
