// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "quic/core/crypto/quic_random.h"
#include <cstdint>
#include <cstring>
#include <iostream>

#include "third_party/boringssl/src/include/openssl/rand.h"
#include "quic/platform/api/quic_bug_tracker.h"
#include "quic/platform/api/quic_logging.h"
#include "common/platform/api/quiche_logging.h"

namespace quic {

namespace {

// Insecure randomness in DefaultRandom uses an implementation of
// xoshiro256++ 1.0 based on code in the public domain from
// <http://prng.di.unimi.it/xoshiro256plusplus.c>.

inline uint64_t Xoshiro256PlusPlusRotLeft(uint64_t x, int k) {
  return (x << k) | (x >> (64 - k));
}

uint64_t Xoshiro256PlusPlus() {
  static thread_local uint64_t rng_state[4];
  static thread_local bool rng_state_initialized = false;
  if (QUIC_PREDICT_FALSE(!rng_state_initialized)) {
    RAND_bytes(reinterpret_cast<uint8_t*>(&rng_state), sizeof(rng_state));
    rng_state_initialized = true;
  }
  const uint64_t result =
      Xoshiro256PlusPlusRotLeft(rng_state[0] + rng_state[3], 23) + rng_state[0];
  const uint64_t t = rng_state[1] << 17;
  rng_state[2] ^= rng_state[0];
  rng_state[3] ^= rng_state[1];
  rng_state[1] ^= rng_state[2];
  rng_state[0] ^= rng_state[3];
  rng_state[2] ^= t;
  rng_state[3] = Xoshiro256PlusPlusRotLeft(rng_state[3], 45);

  for (int i = 0; i < 4; ++i) {
    std::cerr << "Xoshiro256PlusPlus &rng_state[" << i << "]: " << &rng_state[i]
              << std::endl;
  }
  for (int i = 0; i < 4; ++i) {
    std::cerr << "Xoshiro256PlusPlus delta: " << i << ": "
              << (intptr_t)(&rng_state[i]) - (intptr_t)(&rng_state[0])
              << std::endl;
  }
  return result;
}

class DefaultRandom : public QuicRandom {
 public:
  DefaultRandom() {}
  DefaultRandom(const DefaultRandom&) = delete;
  DefaultRandom& operator=(const DefaultRandom&) = delete;
  ~DefaultRandom() override {}

  // QuicRandom implementation
  void RandBytes(void* data, size_t len) override;
  uint64_t RandUint64() override;
  void InsecureRandBytes(void* data, size_t len) override;
  uint64_t InsecureRandUint64() override;
};

void DefaultRandom::RandBytes(void* data, size_t len) {
  RAND_bytes(reinterpret_cast<uint8_t*>(data), len);
}

uint64_t DefaultRandom::RandUint64() {
  uint64_t value;
  RandBytes(&value, sizeof(value));
  return value;
}

void DefaultRandom::InsecureRandBytes(void* data, size_t len) {
  while (len >= sizeof(uint64_t)) {
    uint64_t random_bytes64 = Xoshiro256PlusPlus();
    memcpy(data, &random_bytes64, sizeof(uint64_t));
    data = reinterpret_cast<char*>(data) + sizeof(uint64_t);
    len -= sizeof(uint64_t);
  }
  if (len > 0) {
    QUICHE_DCHECK_LT(len, sizeof(uint64_t));
    uint64_t random_bytes64 = Xoshiro256PlusPlus();
    memcpy(data, &random_bytes64, len);
  }
}

uint64_t DefaultRandom::InsecureRandUint64() {
  return Xoshiro256PlusPlus();
}

}  // namespace

// static
QuicRandom* QuicRandom::GetInstance() {
  static DefaultRandom* random = new DefaultRandom();
  return random;
}

}  // namespace quic
