/*********************************************************
** Copyright (c) 2005
** University of Washington
** Licensed under the terms set forth by University of
** Washington. If you did not sign such a license, you
** are using this software/code illegally and you do not
** have permission to use, modify, or redistribute
** this or any files in this software package.
**
** File: ProgressThreadTest.h
**
**********************************************************/
#ifndef PROGRESSTHREADTEST_H
#define PROGRESSTHREADTEST_H

#include "ProgressThread.h"
#include "UnitTestClass.h"
#include "TestException.h"
#include <unistd.h>
#include <iostream>

#ifdef WIN32
#include <Windows.h>
#endif

class CTestThread : public CProgressThread
{
 public:
  CTestThread() : m_iterations(2), m_sleepCount(1), m_msgid(3), m_testReturnStatus(4) {}
  CTestThread(int iters, int sleepSeconds, int msgid, int returnStatus) 
    : m_iterations(iters), m_sleepCount(sleepSeconds), m_msgid(msgid), m_testReturnStatus(returnStatus) {}

  int Go(THREAD_ID_T tid)
  {
    for(int i = 0 ; i < m_iterations; i++)
      {
	UpdateProgressInfo(m_iterations, i, m_msgid);
#ifdef WIN32
	Sleep(m_sleepCount*1000);
#else
	sleep(m_sleepCount);
#endif
      }
    return m_testReturnStatus;
  }

 private:
  int m_iterations;
  int m_sleepCount;
  int m_msgid;
  int m_testReturnStatus;
};

class CProgressThreadTest : public CUnitTestClass
{
 public:
  CProgressThreadTest() : CUnitTestClass("CProgressThreadTest") {}

  void RunTests()
  {
    TestThread1();
  }

 private:
  void TestThread1()
  {
    BeginTest("TestThread1");
    bool success = true;

    try
    {
      cout << __FILE__ << " line " << __LINE__ << "\n";

      int iters = 2, sleepSeconds = 1, msgid = 3, returnStatus = 4;
      CTestThread t(iters, sleepSeconds, msgid, returnStatus);
      t.Start();
      double current = t.GetProgressInfoCurrent();
      double newCurrent;
      bool currentChanged = false;

      for(int i = 0; i < 6 && !t.GetIsFinished(); i++)
	{
	  cout << "Sleeping...\n";
	  // Sleep 1/2 second
#ifdef WIN32
	  Sleep(500);
#else
	  usleep(500000);
#endif
	  // Check whether thread has finished
	  if ((newCurrent = t.GetProgressInfoCurrent()) != current)
	    {
	      currentChanged = true;
	    }
	  cout << "Current = " << newCurrent << "\n";
	}

      if(!t.GetIsFinished())
	{
	  __throw_message("Thread never finished");
	}
      if(!currentChanged)
	{
	  __throw_message("Thread finished, but 'current' never changed");
	}
      if(t.GetReturnStatus() != returnStatus)
	{
	  cout << "Expected return status " << returnStatus << ", got return status " << t.GetReturnStatus() << "\n";
	  __throw_message("Error in thread testing");
	}
      CProgressThreadManager::Erase(&t);
    }
    catch(CTestException *pEx)
    {
      success = false;
      cout << pEx->Message() << "\n";
      delete pEx;
    }
    catch(...)
    {
      success = false;
      cout << "something's wrong\n";

    }

    EndTest(success);

  }

};
#endif
