// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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 "cobalt/base/token.h"

#include <set>
#include <vector>

#include "base/logging.h"
#include "base/memory/singleton.h"
#include "base/synchronization/lock.h"

namespace base {

namespace {

// TODO: Replace more potential strings with Token, like event names and
//       attribute names.
// TODO: Turn kTagName of HTMLElements into Token.
// TODO: Implement Token friendly containers.
// TODO: Improve the internal storage of Token.  Possibly remove the use of
//       std::string and manage the buffer by ourselves.
class TokenStorage {
 public:
  static TokenStorage* GetInstance() { return Singleton<TokenStorage>::get(); }

  const char* GetStorage(const char* str);

 private:
  friend struct DefaultSingletonTraits<TokenStorage>;

  TokenStorage()
      : hash_table_(Token::kHashSlotCount * Token::kStringsPerSlot) {}

  std::vector<std::string> hash_table_;
  // The collision table contains Tokens whose hash values collide with one of
  // the existing Token.  This should happen very rare.
  std::set<std::string> collision_table_;
  const std::string empty_;
  base::Lock lock_;
};

#if defined(BASE_HASH_USE_HASH_STRUCT)

uint32 hash(const char* str) {
  return BASE_HASH_NAMESPACE::hash<const char*>()(str);
}

#else

uint32 hash(const char* str) { return BASE_HASH_NAMESPACE::hash_value(str); }

#endif  // COMPILER

}  // namespace

Token::Token() : str_(TokenStorage::GetInstance()->GetStorage("")) {}

Token::Token(const char* str)
    : str_(TokenStorage::GetInstance()->GetStorage(str)) {}

Token::Token(const std::string& str)
    : str_(TokenStorage::GetInstance()->GetStorage(str.c_str())) {}

const char* TokenStorage::GetStorage(const char* str) {
  DCHECK(str);

  if (!str || str[0] == 0) {
    return empty_.c_str();
  }

  uint32 slot = hash(str) % Token::kHashSlotCount;
  // First check if we already have this token.
  for (uint32 i = 0; i < Token::kStringsPerSlot; ++i) {
    uint32 index = slot * Token::kStringsPerSlot + i;
    if (hash_table_[index].empty()) {
      break;
    }
    if (hash_table_[index] == str) {
      return hash_table_[index].c_str();
    }
  }

  base::AutoLock auto_lock(lock_);
  // Now try to create this token in the table.
  for (uint32 i = 0; i < Token::kStringsPerSlot; ++i) {
    uint32 index = slot * Token::kStringsPerSlot + i;
    if (hash_table_[index].empty()) {
      hash_table_[index] = str;
      return hash_table_[index].c_str();
    }
  }

  // This should never happen in production as we use a quite large bin size
  // compares to the tokens in the system.  But it is does, we want to ensure
  // that the code can still work without crashing.
  if (collision_table_.empty()) {
    LOG(ERROR) << "Got collisions in Token.";
  }

  std::set<std::string>::iterator iter = collision_table_.find(str);
  if (iter != collision_table_.end()) {
    return iter->c_str();
  }
  return collision_table_.insert(str).first->c_str();
}

}  // namespace base
