#include "testutils.h"
#include "testchunkable.h"
#include <callback.h>

// Very, very wrong, but this is the only way to do it in this version
// of gcc
#define WRAP(args...) wrap(this, &testChunkable::args)

str aiw = readFile("alice30.txt");

int
main(int argc, const char **argv)
{
  srandom(0x6824);

  testChunkable test;
  memSuperblob::create(wrap(&test, &testChunkable::after_blob),
                       fatalCB);

  amain();
}

void
testChunkable::after_blob(ref<memSuperblob> b)
{
  blob = b;
  chunkable::create(b, aiw, WRAP(cycle, 0, 0), fatalCB);
}

void
testChunkable::cycle(int step, int stage, ref<chunkable> ch)
{
  callback<void>::ref cb = WRAP(cycle, step+1, stage, ch);

  ch->debug_dumpChunks();

  warn << "Performing step " << step << " at stage " << stage << "\n";

  if (step == 0) {
    ch->flush(cb, fatalCB);
  } else if (step == 1) {
    ch->marshall(WRAP(after_marshall, cb), fatalCB);
  } else if (step == 2) {
    ch->writeSubstr(ch->chunks.first->length - 1, str("rejects"),
                    cb, fatalCB);
  } else if (step == 3) {
    ch->flush(cb, fatalCB);
  } else if (step == 4) {
    ch->truncate(20000, cb, fatalCB);
  } else if (step == 5) {
    ch->flush(cb, fatalCB);
  } else if (step == 6) {
    ch->truncate(25000, cb, fatalCB);
  } else if (step == 7) {
    ch->flush(cb, fatalCB);
  } else if (step == 8 && stage == 0) {
    chunkable::unmarshall(blob, marshalled, WRAP(cycle, 0, stage+1), fatalCB);
  } else
    exit(0);
}

void
testChunkable::after_marshall(callback<void>::ref cb, chunkable::marshalled m)
{
  marshalled = m;
  cb();
}
