// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * 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.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "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 COPYRIGHT
// OWNER OR CONTRIBUTORS 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.h>
#include <string>
#include "base/util.h"

namespace mozc {
namespace {
const uint32 kFingerPrint32Seed = 0xfd12deff;
const uint32 kFingerPrintSeed0 = 0x6d6f;
const uint32 kFingerPrintSeed1 = 0x7a63;
}  // namespace

#define mix(a,b,c) { \
  a -= b; a -= c; a ^= (c >> 13); \
  b -= c; b -= a; b ^= (a << 8); \
  c -= a; c -= b; c ^= (b >> 13); \
  a -= b; a -= c; a ^= (c >> 12);  \
  b -= c; b -= a; b ^= (a << 16); \
  c -= a; c -= b; c ^= (b >> 5); \
  a -= b; a -= c; a ^= (c >> 3);  \
  b -= c; b -= a; b ^= (a << 10); \
  c -= a; c -= b; c ^= (b >> 15); \
}

uint32 Util::Fingerprint32(const string &key) {
  return Fingerprint32WithSeed(key.data(), key.size(),
                               kFingerPrint32Seed);
}

uint32 Util::Fingerprint32(const char *str, size_t length) {
  return Fingerprint32WithSeed(str, length,
                               kFingerPrint32Seed);
}

uint32 Util::Fingerprint32(const char *str) {
  return Fingerprint32WithSeed(str, strlen(str),
                               kFingerPrint32Seed);
}

uint32 Util::Fingerprint32WithSeed(const string &key,
                                   uint32 seed) {
  return Fingerprint32WithSeed(key.data(), key.size(),
                               seed);
}

uint32 Util::Fingerprint32WithSeed(const char *str,
                                   size_t length,
                                   uint32 seed) {
  uint32 len = static_cast<uint32>(length);
  uint32 a = 0x9e3779b9;
  uint32 b = a;
  uint32 c = seed;

  while (len >= 12) {
    a += (str[0] + ((uint32)str[1] << 8) + ((uint32)str[2] << 16)
          + ((uint32)str[3] << 24));
    b += (str[4] + ((uint32)str[5] << 8) + ((uint32)str[6] << 16)
          + ((uint32)str[7] << 24));
    c += (str[8] + ((uint32)str[9] << 8) + ((uint32)str[10] << 16)
          + ((uint32)str[11] << 24));
    mix(a, b, c);
    str += 12;
    len -= 12;
  }

  c += static_cast<uint32>(length);
  switch (len) {
    case 11:
      c += ((uint32) str[10] << 24);
      FALLTHROUGH_INTENDED;
    case 10:
      c += ((uint32) str[9] << 16);
      FALLTHROUGH_INTENDED;
    case 9:
      c += ((uint32) str[8] << 8);
      FALLTHROUGH_INTENDED;
    case 8:
      b += ((uint32) str[7] << 24);
      FALLTHROUGH_INTENDED;
    case 7:
      b += ((uint32) str[6] << 16);
      FALLTHROUGH_INTENDED;
    case 6:
      b += ((uint32) str[5] << 8);
      FALLTHROUGH_INTENDED;
    case 5:
      b += str[4];
      FALLTHROUGH_INTENDED;
    case 4:
      a += ((uint32) str[3] << 24);
      FALLTHROUGH_INTENDED;
    case 3:
      a += ((uint32) str[2] << 16);
      FALLTHROUGH_INTENDED;
    case 2:
      a += ((uint32) str[1] << 8);
      FALLTHROUGH_INTENDED;
    case 1:
      a += str[0];
      break;
  }
  mix(a, b, c);

  return c;
}

uint32 Util::Fingerprint32WithSeed(const char *str,
                                   uint32 seed) {
  return Fingerprint32WithSeed(str, strlen(str), seed);
}

uint32 Util::Fingerprint32WithSeed(uint32 num, uint32 seed) {
  const char* str = reinterpret_cast<const char*>(&num);
  return Fingerprint32WithSeed(str, sizeof(num), seed);
}

uint64 Util::Fingerprint(const string &key) {
  return Fingerprint(key.data(), key.size());
}

uint64 Util::Fingerprint(const char *str, size_t length) {
  return FingerprintWithSeed(str, length, kFingerPrintSeed0);
}

uint64 Util::FingerprintWithSeed(const string &str, uint32 seed) {
  return FingerprintWithSeed(str.data(), str.size(), seed);
}

uint64 Util::FingerprintWithSeed(const char *str, size_t length, uint32 seed) {
  const uint32 hi = Fingerprint32WithSeed(str, length, seed);
  const uint32 lo = Fingerprint32WithSeed(str, length, kFingerPrintSeed1);
  uint64 result = static_cast<uint64>(hi) << 32 | static_cast<uint64>(lo);
  if ((hi == 0) && (lo < 2)) {
    result ^= GG_ULONGLONG(0x130f9bef94a0a928);
  }
  return result;
}

}  // namespace mozc
