// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include <algorithm>
#include <cstring>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "platform/assert.h"
#include "vm/unit_test.h"
#include "vm/hash_table.h"

namespace dart {

// Various ways to look up strings. Uses length as the hash code to make it
// easy to engineer collisions.
class TestTraits {
 public:
  static bool IsMatch(const char* key, const Object& obj) {
    return String::Cast(obj).Equals(key);
  }
  static uword Hash(const char* key) {
    return static_cast<uword>(strlen(key));
  }
  static bool IsMatch(const Object& a, const Object& b) {
    return a.IsString() && b.IsString() &&
        String::Cast(a).Equals(String::Cast(b));
  }
  static uword Hash(const Object& obj) {
    return String::Cast(obj).Length();
  }
  static RawObject* NewKey(const char* key) {
    return String::New(key);
  }
};


template<typename Table>
void Validate(const Table& table) {
  // Verify consistency of entry state tracking.
  intptr_t num_entries = table.NumEntries();
  intptr_t num_unused = table.NumUnused();
  intptr_t num_occupied = table.NumOccupied();
  intptr_t num_deleted = table.NumDeleted();
  for (intptr_t i = 0; i < num_entries; ++i) {
    EXPECT_EQ(1, table.IsUnused(i) + table.IsOccupied(i) + table.IsDeleted(i));
    num_unused -= table.IsUnused(i);
    num_occupied -= table.IsOccupied(i);
    num_deleted -= table.IsDeleted(i);
  }
  EXPECT_EQ(0, num_unused);
  EXPECT_EQ(0, num_occupied);
  EXPECT_EQ(0, num_deleted);
}


TEST_CASE(HashTable) {
  typedef HashTable<TestTraits, 2, 1> Table;
  Table table(HashTables::New<Table>(5));
  // Ensure that we did get at least 5 entries.
  EXPECT_LE(5, table.NumEntries());
  EXPECT_EQ(0, table.NumOccupied());
  Validate(table);
  EXPECT_EQ(-1, table.FindKey("a"));

  // Insertion and lookup.
  intptr_t a_entry = -1;
  EXPECT(!table.FindKeyOrDeletedOrUnused("a", &a_entry));
  EXPECT_NE(-1, a_entry);
  String& a = String::Handle(String::New("a"));
  table.InsertKey(a_entry, a);
  EXPECT_EQ(1, table.NumOccupied());
  Validate(table);
  EXPECT_EQ(a_entry, table.FindKey("a"));
  EXPECT_EQ(-1, table.FindKey("b"));
  intptr_t a_entry_again = -1;
  EXPECT(table.FindKeyOrDeletedOrUnused("a", &a_entry_again));
  EXPECT_EQ(a_entry, a_entry_again);
  intptr_t b_entry = -1;
  EXPECT(!table.FindKeyOrDeletedOrUnused("b", &b_entry));
  String& b = String::Handle(String::New("b"));
  table.InsertKey(b_entry, b);
  EXPECT_EQ(2, table.NumOccupied());
  Validate(table);

  // Deletion.
  table.DeleteEntry(a_entry);
  EXPECT_EQ(1, table.NumOccupied());
  Validate(table);
  EXPECT_EQ(-1, table.FindKey("a"));
  EXPECT_EQ(b_entry, table.FindKey("b"));
  intptr_t c_entry = -1;
  EXPECT(!table.FindKeyOrDeletedOrUnused("c", &c_entry));
  String& c = String::Handle(String::New("c"));
  table.InsertKey(c_entry, c);
  EXPECT_EQ(2, table.NumOccupied());
  Validate(table);
  EXPECT_EQ(c_entry, table.FindKey("c"));

  // Ensure we can actually reach 5 occupied entries (without expansion).
  {
    intptr_t entry = -1;
    EXPECT(!table.FindKeyOrDeletedOrUnused("d", &entry));
    String& k = String::Handle(String::New("d"));
    table.InsertKey(entry, k);
    EXPECT(!table.FindKeyOrDeletedOrUnused("e", &entry));
    k = String::New("e");
    table.InsertKey(entry, k);
    EXPECT(!table.FindKeyOrDeletedOrUnused("f", &entry));
    k = String::New("f");
    table.InsertKey(entry, k);
    EXPECT_EQ(5, table.NumOccupied());
  }
  table.Release();
}


TEST_CASE(EnumIndexHashMap) {
  typedef EnumIndexHashMap<TestTraits> Table;
  Table table(HashTables::New<Table>(5));
  table.UpdateOrInsert(String::Handle(String::New("a")),
                       String::Handle(String::New("A")));
  EXPECT(table.ContainsKey("a"));
  table.UpdateValue("a", String::Handle(String::New("AAA")));
  String& a_value = String::Handle();
  a_value ^= table.GetOrNull("a");
  EXPECT(a_value.Equals("AAA"));
  Object& null_value = Object::Handle(table.GetOrNull("0"));
  EXPECT(null_value.IsNull());

  // Test on-demand allocation of a new key object using NewKey in traits.
  String& b_value = String::Handle();
  b_value ^=
      table.InsertNewOrGetValue("b", String::Handle(String::New("BBB")));
  EXPECT(b_value.Equals("BBB"));
  {
    // When the key is already present, there should be no allocation.
    NoGCScope no_gc;
    b_value ^= table.InsertNewOrGetValue("b", a_value);
    EXPECT(b_value.Equals("BBB"));
  }
  table.Release();
}


std::string ToStdString(const String& str) {
  EXPECT(str.IsOneByteString());
  std::string result;
  for (intptr_t i = 0; i < str.Length(); ++i) {
    result += static_cast<char>(str.CharAt(i));
  }
  return result;
}


// Checks that 'expected' and 'actual' are equal sets. If 'ordered' is true,
// it also verifies that their iteration orders match, i.e., that actual's
// insertion order coincides with lexicographic order.
template<typename Set>
void VerifyStringSetsEqual(const std::set<std::string>& expected,
                           const Set& actual,
                           bool ordered) {
  // Get actual keys in iteration order.
  Array& keys = Array::Handle(HashTables::ToArray(actual, true));
  // Cardinality must match.
  EXPECT_EQ(static_cast<intptr_t>(expected.size()), keys.Length());
  std::vector<std::string> expected_vec(expected.begin(), expected.end());
  // Check containment.
  for (uintptr_t i = 0; i < expected_vec.size(); ++i) {
    EXPECT(actual.ContainsKey(expected_vec[i].c_str()));
  }
  // Equality, including order, if requested.
  std::vector<std::string> actual_vec;
  String& key = String::Handle();
  for (int i = 0; i < keys.Length(); ++i) {
    key ^= keys.At(i);
    actual_vec.push_back(ToStdString(key));
  }
  if (!ordered) {
    std::sort(actual_vec.begin(), actual_vec.end());
  }
  EXPECT(std::equal(actual_vec.begin(), actual_vec.end(),
                    expected_vec.begin()));
}


// Checks that 'expected' and 'actual' are equal maps. If 'ordered' is true,
// it also verifies that their iteration orders match, i.e., that actual's
// insertion order coincides with lexicographic order.
template<typename Map>
void VerifyStringMapsEqual(const std::map<std::string, int>& expected,
                           const Map& actual,
                           bool ordered) {
  intptr_t expected_size = expected.size();
  // Get actual concatenated (key, value) pairs in iteration order.
  Array& entries = Array::Handle(HashTables::ToArray(actual, true));
  // Cardinality must match.
  EXPECT_EQ(expected_size * 2, entries.Length());
  std::vector<std::pair<std::string, int> > expected_vec(expected.begin(),
                                                         expected.end());
  // Check containment.
  Smi& value = Smi::Handle();
  for (uintptr_t i = 0; i < expected_vec.size(); ++i) {
    std::string key = expected_vec[i].first;
    EXPECT(actual.ContainsKey(key.c_str()));
    value ^= actual.GetOrNull(key.c_str());
    EXPECT_EQ(expected_vec[i].second, value.Value());
  }
  if (!ordered) {
    return;
  }
  // Equality including order.
  std::vector<std::string> actual_vec;
  String& key = String::Handle();
  for (int i = 0; i < expected_size; ++i) {
    key ^= entries.At(2 * i);
    value ^= entries.At(2 * i + 1);
    EXPECT(expected_vec[i].first == ToStdString(key));
    EXPECT_EQ(expected_vec[i].second, value.Value());
  }
}


template<typename Set>
void TestSet(intptr_t initial_capacity, bool ordered) {
  std::set<std::string> expected;
  Set actual(HashTables::New<Set>(initial_capacity));
  // Insert the following strings twice:
  // aaa...aaa (length 26)
  // bbb..bbb
  // ...
  // yy
  // z
  for (int i = 0; i < 2; ++i) {
    for (char ch = 'a'; ch <= 'z'; ++ch) {
      std::string key('z' - ch + 1, ch);
      expected.insert(key);
      bool present = actual.Insert(String::Handle(String::New(key.c_str())));
      EXPECT_EQ((i != 0), present);
      Validate(actual);
      VerifyStringSetsEqual(expected, actual, ordered);
    }
  }
  actual.Clear();
  EXPECT_EQ(0, actual.NumOccupied());
  actual.Release();
}


template<typename Map>
void TestMap(intptr_t initial_capacity, bool ordered) {
  std::map<std::string, int> expected;
  Map actual(HashTables::New<Map>(initial_capacity));
  // Insert the following (strings, int) mapping:
  // aaa...aaa -> 26
  // bbb..bbb -> 25
  // ...
  // yy -> 2
  // z -> 1
  for (int i = 0; i < 2; ++i) {
    for (char ch = 'a'; ch <= 'z'; ++ch) {
      int length = 'z' - ch + 1;
      std::string key(length, ch);
      // Map everything to zero initially, then update to their final values.
      int value = length * i;
      expected[key] = value;
      bool present =
          actual.UpdateOrInsert(String::Handle(String::New(key.c_str())),
                                Smi::Handle(Smi::New(value)));
      EXPECT_EQ((i != 0), present);
      Validate(actual);
      VerifyStringMapsEqual(expected, actual, ordered);
    }
  }
  actual.Clear();
  EXPECT_EQ(0, actual.NumOccupied());
  actual.Release();
}


TEST_CASE(Sets) {
  for (intptr_t initial_capacity = 0;
       initial_capacity < 32;
       ++initial_capacity) {
    TestSet<UnorderedHashSet<TestTraits> >(initial_capacity, false);
    TestSet<EnumIndexHashSet<TestTraits> >(initial_capacity, true);
  }
}


TEST_CASE(Maps) {
  for (intptr_t initial_capacity = 0;
       initial_capacity < 32;
       ++initial_capacity) {
    TestMap<UnorderedHashMap<TestTraits> >(initial_capacity, false);
    TestMap<EnumIndexHashMap<TestTraits> >(initial_capacity, true);
  }
}

}  // namespace dart
