/* Copyright (C) 2007 Josh MacDonald */

#include <stdio.h>

#define PAGE_SIZE 4096

#define SPACE_MAX 131072   // how much memory per process
#define OUTPUT_MAX 1024    // max size for output
#define XD3_ALLOCSIZE 256  // internal size for various buffers
#define IOPT_SIZE 128      // instruction buffer

// SPACE_MAX of 32K is sufficient for most inputs with XD3_COMPLEVEL_1
// XD3_COMPLEVEL_9 requires about 4x more space than XD3_COMPLEVEL_1

#include "xdelta3.h"
#include "xdelta3.c"

typedef struct _context {
  uint8_t *buffer;
  int allocated;
} context_t;

static int max_allocated = 0;

void*
process_alloc (void* opaque, usize_t items, usize_t size)
{
  context_t *ctx = (context_t*) opaque;
  usize_t t = items * size;
  void *ret;

  if (ctx->allocated + t > SPACE_MAX)
    {
      return NULL;
    }

  ret = ctx->buffer + ctx->allocated;
  ctx->allocated += t;
  return ret;
}

void
process_free (void* opaque, void *ptr)
{
}

int
process_page (int            is_encode,
	      int          (*func) (xd3_stream *),
	      const uint8_t *input,
	      usize_t        input_size,
	      const uint8_t *source,
	      uint8_t       *output,
	      usize_t       *output_size,
	      usize_t        output_size_max,
	      int            flags) {

  /* On my x86 this is 1072 of objects on the stack */
  xd3_stream stream;
  xd3_config config;
  xd3_source src;
  context_t *ctx = calloc(SPACE_MAX, 1);
  int ret;

  memset (&config, 0, sizeof(config));

  if (ctx == NULL)
    {
      printf("calloc failed\n");
      return -1;
    }

  ctx->buffer = (uint8_t*)ctx;
  ctx->allocated = sizeof(*ctx);

  config.flags = flags;
  config.winsize = PAGE_SIZE;
  config.sprevsz = PAGE_SIZE;
  config.srcwin_maxsz = PAGE_SIZE;
  config.iopt_size = IOPT_SIZE;
  config.alloc = &process_alloc;
  config.freef = &process_free;
  config.opaque = (void*) ctx;

  src.size = PAGE_SIZE;
  src.blksize = PAGE_SIZE;
  src.onblk = PAGE_SIZE;
  src.curblk = source;
  src.curblkno = 0;

  if ((ret = xd3_config_stream (&stream, &config)) != 0 ||
      (ret = xd3_set_source (&stream, &src)) != 0 ||
      (ret = xd3_process_stream (is_encode,
				 &stream,
				 func, 1,
				 input, input_size,
				 output, output_size,
				 output_size_max)) != 0)
    {
      if (stream.msg != NULL)
	{
	  fprintf(stderr, "stream message: %s\n", stream.msg);
	}
    }

  xd3_free_stream (&stream);
  if (max_allocated < ctx->allocated)
    {
      max_allocated = ctx->allocated;
      fprintf(stderr, "max allocated %d\n", max_allocated);
    }

  free(ctx);
  return ret;
}

int test(int stride, int encode_flags)
{
  uint8_t frompg[PAGE_SIZE];
  uint8_t topg[PAGE_SIZE];
  uint8_t output[OUTPUT_MAX];
  uint8_t reout[PAGE_SIZE];
  usize_t output_size;
  usize_t re_size;
  int i, j, ret;

  for (i = 0; i < PAGE_SIZE; i++)
    {
      topg[i] = frompg[i] = (rand() >> 3 ^ rand() >> 6 ^ rand() >> 9);
    }

  // change 1 byte every stride
  if (stride > 0)
    {
      for (j = stride; j <= PAGE_SIZE; j += stride)
	{
	  topg[j - 1] ^= 0xff;
	}
    }

  if ((ret = process_page (1, xd3_encode_input,
			   topg, PAGE_SIZE,
			   frompg, output,
			   &output_size, OUTPUT_MAX,
			   encode_flags)) != 0)
    {
      fprintf (stderr, "encode failed: stride %u flags 0x%x\n", 
	       stride, encode_flags);
      return ret;
    }

  if ((ret = process_page (0, xd3_decode_input,
			   output, output_size,
			   frompg, reout,
			   &re_size, PAGE_SIZE,
			   0)) != 0)
    {
      fprintf (stderr, "decode failed: stride %u output_size %u flags 0x%x\n",
	       stride, output_size, encode_flags);
      return ret;
    }

  if (output_size > OUTPUT_MAX || re_size != PAGE_SIZE)
    {
      fprintf (stderr, "internal error: %u != %u\n", output_size, re_size);
      return -1;
    }

  for (i = 0; i < PAGE_SIZE; i++)
    {
      if (reout[i] != topg[i])
	{
	  fprintf (stderr, "encode-decode error: position %d\n", i);
	  return -1;
	}
    }

  fprintf(stderr, "stride %d flags 0x%x size %u ", 
	  stride, encode_flags, output_size);
  fprintf(stderr, "%s\n", (ret == 0) ? "OK" : "FAIL");

  return 0;
}

int main()
{
  int stride;
  int level;

  for (level = 1; level < 10; level = (level == 1 ? 3 : level + 3))
    {
      int lflag = level << XD3_COMPLEVEL_SHIFT;

      for (stride = 2; stride <= PAGE_SIZE; stride += 2)
	{
	  test(stride, lflag);
	  test(stride, lflag | XD3_SEC_DJW);
	}
    }

  return 0;
}
