#include "median.h"
#include <strings.h>

// The buffer is cast into this struct.
typedef struct metadata {
  size_t bufferSize;      // Number of bytes available for use.
  size_t nLevels;          // Number of buffers available.
  size_t currentBufferIdx; // The index of the currently active buffer.
  unsigned char data[0];   // The start of the data.
} metadata_t;

typedef uint32_t parity_t;

typedef struct bufferdata {
  parity_t parity;           // The parity of this buffer.
  size_t level;              // The level of this buffer.
  size_t occupancy;          // Number of occupants for this buffer.
} bufferdata_t;


static const parity_t PARITY_NONE  = 0; // The parity is none.
static const parity_t PARITY_LEFT  = 1; // The buffer has LEFT parity.
static const parity_t PARITY_RIGHT = 2; // The buffer has RIGHT parity.

median_error_t median_suggest_buffer_size(double epsilon, size_t maxN, size_t *suggested_size){
  // First check for sane parameters.
  if (maxN <= 0) return MEDIAN_ERROR_INVALID_PARAMETERS;

  // First compute the size of each buffer.
  size_t n = (1.0/epsilon)+ 1;
  // If n is too large, you are looking for too fine an approximation.
  // This is not the right algorithm. Maybe consider random sampling instead.
  if (n > 100000) return MEDIAN_ERROR_INVALID_PARAMETERS;

  // Compute the log of maxN using a divide by 2 loop.
  // There is no need to make this more complicated at this stage. It's not
  // a deep loop function.
  size_t nLevels = 1;
  while((maxN = (maxN >> 1))) nLevels++;

  // This is the total bytes needed.
  // One metadata block. nLevels bufferdata_t blockes.
  // and n * nLevels median_data_t elements.
  *suggested_size = n * nLevels * sizeof(median_data_t) + nLevels * sizeof(bufferdata_t) + sizeof(metadata_t);

  // Things worked. Return MEDIAN_OK
  return MEDIAN_OK;
}
median_error_t median_init_buffer(void * buffer, size_t buffer_size, double epsilon, size_t maxN, median_buffer_t *initialized_buffer){

  // Initialize.
  size_t expectedSize = 0;
  median_error_t error = MEDIAN_OK;

  // First run median_suggest_buffer_size
  if ((error = median_suggest_buffer_size(epsilon,maxN,&expectedSize)) != MEDIAN_OK) return error;
  // Ensure that the buffer is large enough.
  if (expectedSize > buffer_size) return MEDIAN_ERROR_BUFFER_TOO_SMALL;

  // Cast the buffer as metadata_t so that we can initialize the metadata block.
  metadata_t * m = (metadata_t *)buffer;
  // Initialize the metadata block.
  m->bufferSize = buffer_size - sizeof(metadata_t);
  m->nLevels = m->bufferSize/((maxN * sizeof(median_data_t)) + sizeof(bufferdata_t));
  m->currentBufferIdx = 0;
  bzero(m->data, m->bufferSize);

  // cast the data part as an array of bufferdata_t blocks.
  // and initialize each of the blocks.
  bufferdata_t * t = (bufferdata_t *) m->data;
  for(size_t i = 0; i < m->nLevels; i++) {
    t[i].parity = PARITY_NONE;
    t[i].level  = 0;
    t[i].occupancy = 0;
  }

  // Populate the return value.
  *initialized_buffer = (median_buffer_t)buffer;
  return error;
}

median_error_t median_insert_data(median_buffer_t buffer, median_data_t data){
  // First locate the empty buffer.
  return MEDIAN_OK;
}

median_error_t median_output_median(median_buffer_t buffer, median_data_t *approximate_median){
  return MEDIAN_OK;
}
