/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

//       Some ideas of improvements:
//       Break out common init and maybe terminate to separate function(s).
//       How much trace should we have enabled?
//       API error counter, to print info and return -1 if any error.

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#if defined(_WIN32)
#include <conio.h>
#endif

#include "webrtc/voice_engine/test/auto_test/voe_stress_test.h"

#include "webrtc/base/scoped_ptr.h"
#include "webrtc/system_wrappers/include/sleep.h"
#include "webrtc/test/channel_transport/include/channel_transport.h"
#include "webrtc/voice_engine/test/auto_test/voe_standard_test.h"
#include "webrtc/voice_engine/test/auto_test/voe_test_defines.h"
#include "webrtc/voice_engine/voice_engine_defines.h"  // defines build macros

using namespace webrtc;
using namespace test;

namespace voetest {

#define VALIDATE_STRESS(expr)                                   \
    if (expr)                                                   \
    {                                                           \
        printf("Error at line: %i, %s \n", __LINE__, #expr);    \
        printf("Error code: %i \n", base->LastError());  \
    }

#ifdef _WIN32
// Pause if supported
#define PAUSE_OR_SLEEP(x) PAUSE;
#else
// Sleep a bit instead if pause not supported
#define PAUSE_OR_SLEEP(x) SleepMs(x);
#endif

int VoEStressTest::DoTest() {
  int test(-1);
  while (test != 0) {
    test = MenuSelection();
    switch (test) {
      case 0:
        // Quit stress test
        break;
      case 1:
        // All tests
        StartStopTest();
        CreateDeleteChannelsTest();
        MultipleThreadsTest();
        break;
      case 2:
        StartStopTest();
        break;
      case 3:
        CreateDeleteChannelsTest();
        break;
      case 4:
        MultipleThreadsTest();
        break;
      default:
        // Should not be possible
        printf("Invalid selection! (Test code error)\n");
        assert(false);
    }  // switch
  }  // while

  return 0;
}

int VoEStressTest::MenuSelection() {
  printf("------------------------------------------------\n");
  printf("Select stress test\n\n");
  printf(" (0)  Quit\n");
  printf(" (1)  All\n");
  printf("- - - - - - - - - - - - - - - - - - - - - - - - \n");
  printf(" (2)  Start/stop\n");
  printf(" (3)  Create/delete channels\n");
  printf(" (4)  Multiple threads\n");

  const int maxMenuSelection = 4;
  int selection(-1);

  while ((selection < 0) || (selection > maxMenuSelection)) {
    printf("\n: ");
    int retval = scanf("%d", &selection);
    if ((retval != 1) || (selection < 0) || (selection > maxMenuSelection)) {
      printf("Invalid selection!\n");
    }
  }

  return selection;
}

int VoEStressTest::StartStopTest() {
  printf("------------------------------------------------\n");
  printf("Running start/stop test\n");
  printf("------------------------------------------------\n");

  printf("\nNOTE: this thest will fail after a while if Core audio is used\n");
  printf("because MS returns AUDCLNT_E_CPUUSAGE_EXCEEDED (VoE Error 10013).\n");

  // Get sub-API pointers
  VoEBase* base = _mgr.BasePtr();
  VoENetwork* voe_network = _mgr.NetworkPtr();

  // Set trace
  //     VALIDATE_STRESS(base->SetTraceFileName(
  //         GetFilename("VoEStressTest_StartStop_trace.txt")));
  //     VALIDATE_STRESS(base->SetDebugTraceFileName(
  //         GetFilename("VoEStressTest_StartStop_trace_debug.txt")));
  //     VALIDATE_STRESS(base->SetTraceFilter(kTraceStateInfo |
  //         kTraceWarning | kTraceError |
  //         kTraceCritical | kTraceApiCall |
  //         kTraceMemory | kTraceInfo));
  VALIDATE_STRESS(base->Init());
  VALIDATE_STRESS(base->CreateChannel());

  ///////////// Start test /////////////

  int numberOfLoops(2000);
  int loopSleep(200);
  int i(0);
  int markInterval(20);

  printf("Running %d loops with %d ms sleep. Mark every %d loop. \n",
         numberOfLoops, loopSleep, markInterval);
  printf("Test will take approximately %d minutes. \n",
         numberOfLoops * loopSleep / 1000 / 60 + 1);

  rtc::scoped_ptr<VoiceChannelTransport> voice_channel_transport(
      new VoiceChannelTransport(voe_network, 0));

  for (i = 0; i < numberOfLoops; ++i) {
    voice_channel_transport->SetSendDestination("127.0.0.1", 4800);
    voice_channel_transport->SetLocalReceiver(4800);
    VALIDATE_STRESS(base->StartReceive(0));
    VALIDATE_STRESS(base->StartPlayout(0));
    VALIDATE_STRESS(base->StartSend(0));
    if (!(i % markInterval))
      MARK();
    SleepMs(loopSleep);
    VALIDATE_STRESS(base->StopSend(0));
    VALIDATE_STRESS(base->StopPlayout(0));
    VALIDATE_STRESS(base->StopReceive(0));
  }
  ANL();

  VALIDATE_STRESS(voice_channel_transport->SetSendDestination("127.0.0.1",
                                                              4800));
  VALIDATE_STRESS(voice_channel_transport->SetLocalReceiver(4800));
  VALIDATE_STRESS(base->StartReceive(0));
  VALIDATE_STRESS(base->StartPlayout(0));
  VALIDATE_STRESS(base->StartSend(0));
  printf("Verify that audio is good. \n");
  PAUSE_OR_SLEEP(20000);
  VALIDATE_STRESS(base->StopSend(0));
  VALIDATE_STRESS(base->StopPlayout(0));
  VALIDATE_STRESS(base->StopReceive(0));

  ///////////// End test /////////////


  // Terminate
  VALIDATE_STRESS(base->DeleteChannel(0));
  VALIDATE_STRESS(base->Terminate());

  printf("Test finished \n");

  return 0;
}

int VoEStressTest::CreateDeleteChannelsTest() {
  printf("------------------------------------------------\n");
  printf("Running create/delete channels test\n");
  printf("------------------------------------------------\n");

  // Get sub-API pointers
  VoEBase* base = _mgr.BasePtr();

  // Set trace
  //     VALIDATE_STRESS(base->SetTraceFileName(
  //          GetFilename("VoEStressTest_CreateChannels_trace.txt")));
  //     VALIDATE_STRESS(base->SetDebugTraceFileName(
  //          GetFilename("VoEStressTest_CreateChannels_trace_debug.txt")));
  //     VALIDATE_STRESS(base->SetTraceFilter(kTraceStateInfo |
  //         kTraceWarning | kTraceError |
  //         kTraceCritical | kTraceApiCall |
  //         kTraceMemory | kTraceInfo));
  VALIDATE_STRESS(base->Init());

  ///////////// Start test /////////////

  int numberOfLoops(10000);
  int loopSleep(10);
  int i(0);
  int markInterval(200);

  printf("Running %d loops with %d ms sleep. Mark every %d loop. \n",
         numberOfLoops, loopSleep, markInterval);
  printf("Test will take approximately %d minutes. \n",
         numberOfLoops * loopSleep / 1000 / 60 + 1);

  //       Some possible extensions include:
  //       Different sleep times (fixed or random) or zero.
  //       Start call on all or some channels.
  //       Two parts: first have a slight overweight to creating channels,
  //       then to deleting. (To ensure we hit max channels and go to zero.)
  //       Make sure audio is OK after test has finished.

  // Set up, start with maxChannels/2 channels
  const int maxChannels = 100;
  VALIDATE_STRESS(maxChannels < 1); // Should always have at least one channel
  bool* channelState = new bool[maxChannels];
  memset(channelState, 0, maxChannels * sizeof(bool));
  int channel(0);
  int noOfActiveChannels(0);
  for (i = 0; i < (maxChannels / 2); ++i) {
    channel = base->CreateChannel();
    VALIDATE_STRESS(channel < 0);
    if (channel >= 0) {
      channelState[channel] = true;
      ++noOfActiveChannels;
    }
  }
  srand((unsigned int) time(NULL));
  bool action(false);
  double rnd(0.0);
  int res(0);

  // Create/delete channels with slight
  for (i = 0; i < numberOfLoops; ++i) {
    // Randomize action (create or delete channel)
    action = rand() <= (RAND_MAX / 2);
    if (action) {
      if (noOfActiveChannels < maxChannels) {
        // Create new channel
        channel = base->CreateChannel();
        VALIDATE_STRESS(channel < 0);
        if (channel >= 0) {
          channelState[channel] = true;
          ++noOfActiveChannels;
        }
      }
    } else {
      if (noOfActiveChannels > 0) {
        // Delete random channel that's created [0, maxChannels - 1]
        do {
          rnd = static_cast<double> (rand());
          channel = static_cast<int> (rnd /
                                      (static_cast<double> (RAND_MAX) + 1.0f) *
                                      maxChannels);
        } while (!channelState[channel]); // Must find a created channel

        res = base->DeleteChannel(channel);
        VALIDATE_STRESS(0 != res);
        if (0 == res) {
          channelState[channel] = false;
          --noOfActiveChannels;
        }
      }
    }

    if (!(i % markInterval))
      MARK();
    SleepMs(loopSleep);
  }
  ANL();

  delete[] channelState;

  ///////////// End test /////////////


  // Terminate
  VALIDATE_STRESS(base->Terminate()); // Deletes all channels

  printf("Test finished \n");

  return 0;
}

int VoEStressTest::MultipleThreadsTest() {
  printf("------------------------------------------------\n");
  printf("Running multiple threads test\n");
  printf("------------------------------------------------\n");

  // Get sub-API pointers
  VoEBase* base = _mgr.BasePtr();

  // Set trace
  //     VALIDATE_STRESS(base->SetTraceFileName(
  //        GetFilename("VoEStressTest_MultipleThreads_trace.txt")));
  //     VALIDATE_STRESS(base->SetDebugTraceFileName(
  //        GetFilename("VoEStressTest_MultipleThreads_trace_debug.txt")));
  //     VALIDATE_STRESS(base->SetTraceFilter(kTraceStateInfo |
  //        kTraceWarning | kTraceError |
  //        kTraceCritical | kTraceApiCall |
  //        kTraceMemory | kTraceInfo));

  // Init
  VALIDATE_STRESS(base->Init());
  VALIDATE_STRESS(base->CreateChannel());

  ///////////// Start test /////////////

  int numberOfLoops(10000);
  int loopSleep(0);
  int i(0);
  int markInterval(1000);

  printf("Running %d loops with %d ms sleep. Mark every %d loop. \n",
         numberOfLoops, loopSleep, markInterval);
  printf("Test will take approximately %d minutes. \n",
         numberOfLoops * loopSleep / 1000 / 60 + 1);

  srand((unsigned int) time(NULL));
  int rnd(0);

  // Start extra thread
  _ptrExtraApiThread = ThreadWrapper::CreateThread(RunExtraApi, this,
                                                   "StressTestExtraApiThread");
  VALIDATE_STRESS(!_ptrExtraApiThread->Start());

  //       Some possible extensions include:
  //       Add more API calls to randomize
  //       More threads
  //       Different sleep times (fixed or random).
  //       Make sure audio is OK after test has finished.

  // Call random API functions here and in extra thread, ignore any error
  for (i = 0; i < numberOfLoops; ++i) {
    // This part should be equal to the marked part in the extra thread
    // --- BEGIN ---
    rnd = rand();
    if (rnd < (RAND_MAX / 2)) {
      // Start playout
      base->StartPlayout(0);
    } else {
      // Stop playout
      base->StopPlayout(0);
    }
    // --- END ---

    if (!(i % markInterval))
      MARK();
    SleepMs(loopSleep);
  }
  ANL();

  // Stop extra thread
  VALIDATE_STRESS(!_ptrExtraApiThread->Stop());

  ///////////// End test /////////////

  // Terminate
  VALIDATE_STRESS(base->Terminate()); // Deletes all channels

  printf("Test finished \n");

  return 0;
}

// Thread functions

bool VoEStressTest::RunExtraApi(void* ptr) {
  return static_cast<VoEStressTest*> (ptr)->ProcessExtraApi();
}

bool VoEStressTest::ProcessExtraApi() {
  // Prepare
  VoEBase* base = _mgr.BasePtr();
  int rnd(0);

  // Call random API function, ignore any error

  // This part should be equal to the marked part in the main thread
  // --- BEGIN ---
  rnd = rand();
  if (rnd < (RAND_MAX / 2)) {
    // Start playout
    base->StartPlayout(0);
  } else {
    // Stop playout
    base->StopPlayout(0);
  }
  // --- END ---

  return true;
}

}  // namespace voetest
