/*
 * libjingle
 * Copyright 2004--2005, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <string>
#include "talk/base/common.h"
#include "talk/xmllite/xmlelement.h"
#include "talk/xmllite/qname.h"
#include "talk/xmllite/xmlconstants.h"

namespace buzz {

static int QName_Hash(const std::string & ns, const char * local) {
  int result = static_cast<int>(ns.size()) * 101;
  while (*local) {
    result *= 19;
    result += *local;
    local += 1;
  }
  return result;
}

static const int bits = 9;
static QName::Data * get_qname_table() {
  static QName::Data qname_table[1 << bits];
  return qname_table;
}

static QName::Data *
AllocateOrFind(const std::string & ns, const char * local) {
  int index = QName_Hash(ns, local);
  int increment = index >> (bits - 1) | 1;
  QName::Data * qname_table = get_qname_table();
  for (;;) {
    index &= ((1 << bits) - 1);
    if (!qname_table[index].Occupied()) {
      return new QName::Data(ns, local);
    }
    if (qname_table[index].localPart_ == local &&
        qname_table[index].namespace_ == ns) {
      qname_table[index].AddRef();
      return qname_table + index;
    }
    index += increment;
  }
}

static QName::Data *
Add(const std::string & ns, const char * local) {
  int index = QName_Hash(ns, local);
  int increment = index >> (bits - 1) | 1;
  QName::Data * qname_table = get_qname_table();
  for (;;) {
    index &= ((1 << bits) - 1);
    if (!qname_table[index].Occupied()) {
      qname_table[index].namespace_ = ns;
      qname_table[index].localPart_ = local;
      qname_table[index].AddRef(); // AddRef twice so it's never deleted
      qname_table[index].AddRef();
      return qname_table + index;
    }
    if (qname_table[index].localPart_ == local &&
        qname_table[index].namespace_ == ns) {
      qname_table[index].AddRef();
      return qname_table + index;
    }
    index += increment;
  }
}

QName::~QName() {
  data_->Release();
}

QName::QName() : data_(QN_EMPTY.data_) {
  data_->AddRef();
}

QName::QName(bool add, const std::string & ns, const char * local) :
  data_(add ? Add(ns, local) : AllocateOrFind(ns, local)) {}

QName::QName(bool add, const std::string & ns, const std::string & local) :
  data_(add ? Add(ns, local.c_str()) : AllocateOrFind(ns, local.c_str())) {}

QName::QName(const std::string & ns, const char * local) :
  data_(AllocateOrFind(ns, local)) {}

static std::string
QName_LocalPart(const std::string & name) {
  size_t i = name.rfind(':');
  if (i == std::string::npos)
    return name;
  return name.substr(i + 1);
}

static std::string
QName_Namespace(const std::string & name) {
  size_t i = name.rfind(':');
  if (i == std::string::npos)
    return STR_EMPTY;
  return name.substr(0, i);
}

QName::QName(const std::string & mergedOrLocal) :
  data_(AllocateOrFind(QName_Namespace(mergedOrLocal),
                 QName_LocalPart(mergedOrLocal).c_str())) {}

std::string
QName::Merged() const {
  if (data_->namespace_ == STR_EMPTY)
    return data_->localPart_;

  std::string result(data_->namespace_);
  result.reserve(result.length() + 1 + data_->localPart_.length());
  result += ':';
  result += data_->localPart_;
  return result;
}

bool
QName::operator==(const QName & other) const {
  return other.data_ == data_ ||
      (data_->localPart_ == other.data_->localPart_ &&
       data_->namespace_ == other.data_->namespace_);
}

int
QName::Compare(const QName & other) const {
  if (data_ == other.data_)
    return 0;

  int result = data_->localPart_.compare(other.data_->localPart_);
  if (result)
    return result;

  return data_->namespace_.compare(other.data_->namespace_);
}

}
