/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set et sw=2 ts=2: */
/***************************************************************************
 *            test_init.cc
 *
 *  Mon Sep  2 14:02:16 CEST 2013
 *  Copyright 2013 Bent Bisballe Nyeng
 *  deva@aasimon.org
 ****************************************************************************/

/*
 *  This file is part of lrtp.
 *
 * lrtp is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * lrtp 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with lrtp; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
#include <cppunit/extensions/HelperMacros.h>

#include <lrtp.h>

#include <stdio.h>

#include <string>
#include <vector>

#define KEY "123456789012345678901234567890123456789012345678901234567890"
#define SSRC 1234567890

class test_conn_class : public CppUnit::TestFixture
{
  CPPUNIT_TEST_SUITE(test_conn_class);
	CPPUNIT_TEST(test_raw);
	CPPUNIT_TEST_SUITE_END();

public:
	void setUp() {}
	void tearDown() {}

	void test_raw() {
    char frame[5];
    int pkg_size = 4;

    std::vector<std::string> packets;
    unsigned int csrc = 42;

    { // Encode
      struct lrtp_t *lrtp = lrtp_init(KEY, SSRC);
      
      struct lrtp_profile_t *profile =
        lrtp_create_profile(lrtp, PROFILE_RAW, csrc,
                            OPTION_RAW_PKG_SIZE, pkg_size,
                            OPTION_END);
      
      char num = 0;

      char packet[16*1024];
      size_t size = sizeof(packet);
      
      for(unsigned int ts = 0; ts < 8; ts++) {

        for(int i = 0; i < sizeof(frame); i++) frame[i] = num++;

        int ret = 0;
        ret = lrtp_enqueue_frame(profile, frame, sizeof(frame));
        while( (ret = lrtp_pack(lrtp, packet, sizeof(packet))) != 0) {
          std::string p;
          p.append(packet, ret);
          packets.push_back(p);
          //dump("pkg", packet, ret);
        }
      }
      
      lrtp_destroy_profile(lrtp, csrc);
      
      lrtp_close(lrtp);
    }
    
    { // Decode
      struct lrtp_t *lrtp = lrtp_init(KEY, SSRC);
      
      struct lrtp_profile_t *profile =
        lrtp_create_profile(lrtp, PROFILE_RAW, csrc,
                            OPTION_RAW_PKG_SIZE, pkg_size,
                            OPTION_END);
      
      char frame[16*1024];
      size_t framesize = sizeof(frame);
      
      int cnt = 0;
      
      char num = 0;

      std::vector<std::string>::iterator i = packets.begin();
      while(i != packets.end()) {
        size_t packetsize = i->size();
        // printf("unpack sz: %d\n", packetsize);
        const char *packet = i->data();
        unsigned int ts;
        
        framesize = sizeof(frame);
        
        lrtp_unpack(lrtp, packet, packetsize);
        int ret;
        while((ret = lrtp_dequeue_frame(lrtp, frame, framesize, &csrc, &ts))
              != 0) {
          //printf("Got %d bytes, csrc %d, ts: %d\n", ret, csrc, ts);

          int err = 0;
          for(int i = 0; i < ret; i++) {
            err += abs(frame[i] - num++);
          }
          CPPUNIT_ASSERT_EQUAL(0, err);

          //dump("pkg", frame, ret);
        }
        
        i++;
      }
      
      lrtp_destroy_profile(lrtp, csrc);
      lrtp_close(lrtp);
    }
	}
};

// Registers the fixture into the 'registry'
CPPUNIT_TEST_SUITE_REGISTRATION(test_conn_class);