#include "header.h"

namespace sframe {

static size_t
uint_size(uint64_t val)
{
  for (unsigned int i = 0; i < 8; i += 1) {
    if ((val >> (8 * i)) == 0) {
      return i;
    }
  }

  return 8;
}

void
encode_uint(uint64_t val, output_bytes buffer)
{
  size_t size = buffer.size();
  for (size_t i = 0; i < size && i < 8; i++) {
    buffer[size - i - 1] = uint8_t(val >> (8 * i));
  }
}

static uint64_t
decode_uint(input_bytes data)
{
  uint64_t val = 0;
  for (size_t i = 0; i < data.size(); i++) {
    val = (val << 8) + static_cast<uint64_t>(data[i]);
  }
  return val;
}

static size_t
kid_size(KeyID key_id)
{
  if (key_id < 0x08) {
    return 0;
  } else {
    return uint_size(key_id);
  }
}

static size_t
ctr_size(Counter counter)
{
  const auto ctr_size = uint_size(counter);
  if (ctr_size == 0) {
    // CTR always takes at least one byte
    return 1;
  }

  return ctr_size;
}

Header::Header(KeyID key_id_in, Counter counter_in)
  : key_id(key_id_in)
  , counter(counter_in)
  , key_id_size(kid_size(key_id))
  , counter_size(ctr_size(counter))
{
  auto buffer_out = output_bytes(buffer);
  buffer_out[0] = uint8_t((counter_size - 1) << 4);
  if (key_id < 0x08) {
    buffer_out[0] |= static_cast<uint8_t>(key_id);
  } else {
    buffer_out[0] |= static_cast<uint8_t>(0x08 | key_id_size);
    encode_uint(key_id, buffer_out.subspan(1, key_id_size));
  }

  encode_uint(counter, buffer_out.subspan(1 + key_id_size, counter_size));
}

Header
Header::parse(input_bytes buffer)
{
  if (buffer.size() < min_size) {
    throw buffer_too_small_error("Ciphertext too small to decode header");
  }

  auto cfg = buffer[0];
  auto ctr_size = size_t((cfg >> 4) & 0x07) + 1;
  auto kid_long = (cfg & 0x08) > 0;
  auto kid_size = size_t(cfg & 0x07);

  auto key_id = KeyID(kid_size);
  if (kid_long) {
    if (buffer.size() < 1 + kid_size) {
      throw buffer_too_small_error("Ciphertext too small to decode KID");
    }

    key_id = KeyID(decode_uint(buffer.subspan(1, kid_size)));
  } else {
    kid_size = 0;
  }

  auto total_size = 1 + ctr_size + kid_size;

  if (buffer.size() < 1 + kid_size + ctr_size) {
    throw buffer_too_small_error("Ciphertext too small to decode CTR");
  }
  auto counter = Counter(decode_uint(buffer.subspan(1 + kid_size, ctr_size)));

  return Header(key_id, counter, kid_size, ctr_size, buffer.subspan(0, total_size));
}

Header::Header(KeyID key_id_in,
               Counter counter_in,
               size_t key_id_size,
               size_t counter_size,
               input_bytes encoded)
  : key_id(key_id_in)
  , counter(counter_in)
  , key_id_size(key_id_size)
  , counter_size(counter_size)
{
  std::copy(encoded.begin(), encoded.end(), buffer.begin());
}

input_bytes
Header::encoded() const
{
  return input_bytes(buffer).subspan(0, size());
}

size_t
Header::size() const
{
  return 1 + key_id_size + counter_size;
}

} // namespace sframe
