/* Copyright 2015 Pierre Ossman <ossman@cendio.se> for Cendio AB
 * 
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this software; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
 * USA.
 */

/*
 * This program reads files produced by TightVNC's/TurboVNC's
 * compare-encodings. It is basically a dump of the RFB protocol
 * from the server side from the ServerInit message and forward.
 * It is assumed that the client is using a bgr888 (LE) pixel
 * format.
 */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/time.h>

#include <rdr/Exception.h>
#include <rdr/FileInStream.h>

#include <rfb/CConnection.h>
#include <rfb/CMsgReader.h>
#include <rfb/PixelBuffer.h>
#include <rfb/PixelFormat.h>

#include "util.h"

// FIXME: Files are always in this format
static const rfb::PixelFormat filePF(32, 24, false, true, 255, 255, 255, 0, 8, 16);

class CConn : public rfb::CConnection {
public:
  CConn(const char *filename);
  ~CConn();

  virtual void initDone();
  virtual void setPixelFormat(const rfb::PixelFormat& pf);
  virtual void setCursor(int, int, const rfb::Point&, const rdr::U8*);
  virtual void framebufferUpdateStart();
  virtual void framebufferUpdateEnd();
  virtual void setColourMapEntries(int, int, rdr::U16*);
  virtual void bell();
  virtual void serverCutText(const char*);

public:
  double cpuTime;

protected:
  rdr::FileInStream *in;
};

CConn::CConn(const char *filename)
{
  cpuTime = 0.0;

  in = new rdr::FileInStream(filename);
  setStreams(in, NULL);

  // Need to skip the initial handshake
  setState(RFBSTATE_INITIALISATION);
  // That also means that the reader and writer weren't setup
  setReader(new rfb::CMsgReader(this, in));
}

CConn::~CConn()
{
  delete in;
}

void CConn::initDone()
{
  setFramebuffer(new rfb::ManagedPixelBuffer(filePF,
                                             server.width(),
                                             server.height()));
}

void CConn::setPixelFormat(const rfb::PixelFormat& pf)
{
  // Override format
  CConnection::setPixelFormat(filePF);
}

void CConn::setCursor(int, int, const rfb::Point&, const rdr::U8*)
{
}

void CConn::framebufferUpdateStart()
{
  CConnection::framebufferUpdateStart();

  startCpuCounter();
}

void CConn::framebufferUpdateEnd()
{
  CConnection::framebufferUpdateEnd();

  endCpuCounter();

  cpuTime += getCpuCounter();
}

void CConn::setColourMapEntries(int, int, rdr::U16*)
{
}

void CConn::bell()
{
}

void CConn::serverCutText(const char*)
{
}

struct stats
{
  double decodeTime;
  double realTime;
};

static struct stats runTest(const char *fn)
{
  CConn *cc;
  struct timeval start, stop;
  struct stats s;

  gettimeofday(&start, NULL);

  try {
    cc = new CConn(fn);
  } catch (rdr::Exception& e) {
    fprintf(stderr, "Failed to open rfb file: %s\n", e.str());
    exit(1);
  }

  try {
    while (true)
      cc->processMsg();
  } catch (rdr::EndOfStream& e) {
  } catch (rdr::Exception& e) {
    fprintf(stderr, "Failed to run rfb file: %s\n", e.str());
    exit(1);
  }

  gettimeofday(&stop, NULL);

  s.decodeTime = cc->cpuTime;
  s.realTime = (double)stop.tv_sec - start.tv_sec;
  s.realTime += ((double)stop.tv_usec - start.tv_usec)/1000000.0;

  delete cc;

  return s;
}

static void sort(double *array, int count)
{
  bool sorted;
  int i;
  do {
    sorted = true;
    for (i = 1;i < count;i++) {
      if (array[i-1] > array[i]) {
        double d;
        d = array[i];
        array[i] = array[i-1];
        array[i-1] = d;
        sorted = false;
      }
    }
  } while (!sorted);
}

static const int runCount = 9;

int main(int argc, char **argv)
{
  int i;
  struct stats runs[runCount];
  double values[runCount], dev[runCount];
  double median, meddev;

  if (argc != 2) {
    printf("Syntax: %s <rfb file>\n", argv[0]);
    return 1;
  }

  // Warmup
  runTest(argv[1]);

  // Multiple runs to get a good average
  for (i = 0;i < runCount;i++)
    runs[i] = runTest(argv[1]);

  // Calculate median and median deviation for CPU usage
  for (i = 0;i < runCount;i++)
    values[i] = runs[i].decodeTime;

  sort(values, runCount);
  median = values[runCount/2];

  for (i = 0;i < runCount;i++)
    dev[i] = fabs((values[i] - median) / median) * 100;

  sort(dev, runCount);
  meddev = dev[runCount/2];

  printf("CPU time: %g s (+/- %g %%)\n", median, meddev);

  // And for CPU core usage
  for (i = 0;i < runCount;i++)
    values[i] = runs[i].decodeTime / runs[i].realTime;

  sort(values, runCount);
  median = values[runCount/2];

  for (i = 0;i < runCount;i++)
    dev[i] = fabs((values[i] - median) / median) * 100;

  sort(dev, runCount);
  meddev = dev[runCount/2];

  printf("Core usage: %g (+/- %g %%)\n", median, meddev);

  return 0;
}
