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

// Author: jmaessen@google.com (Jan-Willem Maessen)

#include "pagespeed/kernel/util/hashed_nonce_generator.h"

#include <unistd.h>

#include "base/logging.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/hasher.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/util/nonce_generator.h"

namespace net_instaweb {

HashedNonceGenerator::HashedNonceGenerator(
    const Hasher* hasher, StringPiece key, AbstractMutex* mutex)
    : NonceGenerator(mutex),
      hasher_(hasher),
      key_size_(key.size() - sizeof(counter_)) {
  DCHECK_LE(2 * hasher->RawHashSizeInBytes(), static_cast<int>(key.size()));
  // Allocate enough space in key_ to hold future data for hashing.  Note in
  // particular that we use the last sizeof(counter_) bits of the passed in key
  // to initialize counter_, and thus exclude it from key_size_.  But we will
  // ultimately need to buffer the initial key_size_ bytes of the passed-in key,
  // the counter_, and the pid.
  char *key_data = new char[key_size_ + sizeof(counter_) + sizeof(pid_t)];
  memcpy(key_data, key.data(), key_size_);
  memcpy(&counter_, key.data() + key_size_, sizeof(counter_));
  key_.reset(key_data);
  counter_ = hasher_->HashToUint64(key);
}

HashedNonceGenerator::~HashedNonceGenerator() { }

uint64 HashedNonceGenerator::NewNonceImpl() {
  ++counter_;
  // We look up the pid here and include it because we may have forked since
  // this HashedNonceGenerator was created, and we want to make sure the forked
  // values yield distinct nonce streams.
  pid_t pid = getpid();
  // We append data to key_, then hash the whole buffer.
  memcpy(&key_[key_size_], &counter_, sizeof(counter_));
  memcpy(&key_[key_size_ + sizeof(counter_)], &pid, sizeof(pid));
  return hasher_->HashToUint64(
      StringPiece(key_.get(), key_size_ + sizeof(counter_) + sizeof(pid)));
}

}  // namespace net_instaweb
