/* $Id$
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version
 * 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>
#include "capu/os/Thread.h"
#include "util/EtchCircularQueue.h"

TEST(EtchCirclerQueueTest, constructorTest) {
  EtchCircularQueue *queue = NULL;
  queue = new EtchCircularQueue(25);
  EXPECT_TRUE(queue != NULL);
  EXPECT_TRUE(queue->getSize() == 25);
  delete queue;
  queue = new EtchCircularQueue();
  EXPECT_TRUE(queue->getSize() == 10);
  delete queue;
}

TEST(EtchCirclerQueueTest, putAndGetTest) {
  EtchCircularQueue* queue = new EtchCircularQueue;

  EtchMailbox::EtchElement* e1 = NULL;

  EXPECT_EQ(ETCH_EINVAL, queue->get(&e1, -1));
  EXPECT_EQ(ETCH_TIMEOUT, queue->get(&e1, 1));

  EXPECT_EQ(0, queue->getCount());
  EXPECT_TRUE(queue->isEmpty());
  EXPECT_FALSE(queue->isFull());

  for (capu::int32_t i = 0; i < 100000; i++) {
    EtchMailbox::EtchElement* e2 = new EtchMailbox::EtchElement(NULL, NULL);
    EtchMailbox::EtchElement* e3 = NULL;

    EXPECT_EQ(ETCH_OK, queue->put(e2));
    EXPECT_FALSE(queue->isEmpty());

    EXPECT_EQ(ETCH_OK, queue->get(&e3));
    EXPECT_EQ(e2, e3);
    EXPECT_EQ(0, queue->getCount());
    EXPECT_TRUE(queue->isEmpty());
    delete e2;
  }

  EtchMailbox::EtchElement * e4 = new EtchMailbox::EtchElement(NULL, NULL);
  EtchMailbox::EtchElement * e5 = new EtchMailbox::EtchElement(NULL, NULL);
  EtchMailbox::EtchElement * e6 = new EtchMailbox::EtchElement(NULL, NULL);
  EtchMailbox::EtchElement * e7 = NULL;

  // default get
  EXPECT_EQ(ETCH_OK, queue->put(e4));
  EXPECT_EQ(ETCH_OK, queue->put(e5));
  EXPECT_EQ(ETCH_OK, queue->put(e6));
  EXPECT_EQ(ETCH_OK, queue->get(&e7));
  EXPECT_EQ(e4, e7);
  e7 = NULL;
  EXPECT_EQ(ETCH_OK, queue->get(&e7));
  EXPECT_EQ(e5, e7);
  e7 = NULL;
  EXPECT_EQ(ETCH_OK, queue->get(&e7));
  EXPECT_EQ(e6, e7);
  e7 = NULL;

  // timeout get
  EXPECT_EQ(ETCH_OK, queue->put(e4, -1));
  EXPECT_EQ(ETCH_OK, queue->put(e5, -1));
  EXPECT_EQ(ETCH_OK, queue->put(e6, -1));
  EXPECT_EQ(ETCH_OK, queue->get(&e7, -1));
  EXPECT_EQ(e4, e7);
  e7 = NULL;
  EXPECT_EQ(ETCH_OK, queue->get(&e7, -1));
  EXPECT_EQ(e5, e7);
  e7 = NULL;
  EXPECT_EQ(ETCH_OK, queue->get(&e7, -1));
  EXPECT_EQ(e6, e7);
  e7 = NULL;

  // timeout get
  EXPECT_EQ(ETCH_OK, queue->put(e4, 1));
  EXPECT_EQ(ETCH_OK, queue->put(e5, 1));
  EXPECT_EQ(ETCH_OK, queue->put(e6, 1));
  EXPECT_EQ(ETCH_OK, queue->get(&e7, 1));
  EXPECT_EQ(e4, e7);
  e7 = NULL;
  EXPECT_EQ(ETCH_OK, queue->get(&e7, 1));
  EXPECT_EQ(e5, e7);
  e7 = NULL;
  EXPECT_EQ(ETCH_OK, queue->get(&e7, 1));
  EXPECT_EQ(e6, e7);
  e7 = NULL;

  delete e4;
  delete e5;
  delete e6;
  delete queue;
}

TEST(EtchCirclerQueueTest, fullTest) {
  EtchCircularQueue* queue = new EtchCircularQueue(1);

  EtchMailbox::EtchElement* e1 = new EtchMailbox::EtchElement(NULL, NULL);
  EtchMailbox::EtchElement* e2 = NULL;

  EXPECT_FALSE(queue->isFull());
  EXPECT_EQ(ETCH_OK, queue->put(e1));
  EXPECT_TRUE(queue->isFull());
  EXPECT_EQ(ETCH_OK, queue->get(&e2));
  EXPECT_EQ(e1, e2);
  e2 = NULL;
  EXPECT_FALSE(queue->isFull());

  // queue overrun
  EXPECT_EQ(ETCH_OK, queue->put(e1));
  EXPECT_EQ(ETCH_EINVAL, queue->put(e1, -1));
  EXPECT_EQ(ETCH_TIMEOUT, queue->put(e1, 1));
  EXPECT_EQ(ETCH_OK, queue->get(&e2));
  EXPECT_EQ(e1, e2);
  e2 = NULL;

  delete e1;
  delete queue;
}

TEST(EtchCirclerQueueTest, closeTest) {
  EtchCircularQueue* queue = new EtchCircularQueue(1);

  EtchMailbox::EtchElement * e1 = new EtchMailbox::EtchElement(NULL, NULL);
  EtchMailbox::EtchElement * e2 = NULL;

  EXPECT_FALSE(queue->isClosed());
  queue->close();
  EXPECT_TRUE(queue->isClosed());

  EXPECT_EQ(ETCH_ERROR, queue->get(&e2));
  EXPECT_EQ(ETCH_EINVAL, queue->get(&e2, -1));
  EXPECT_EQ(ETCH_ERROR, queue->get(&e2, 0));
  EXPECT_EQ(ETCH_ERROR, queue->get(&e2, 1));

  delete e1;
  delete queue;
}

namespace {

class R1 : public capu::Runnable {
public:
  R1(EtchCircularQueue* queue) {
    mQueue = queue;
  }

  void run() {
    // Producer
    for(capu::int32_t i = 0; i < 2000; i++) {
      EtchMailbox::EtchElement * e1 = new EtchMailbox::EtchElement(NULL, NULL);
      EXPECT_EQ(ETCH_OK, mQueue->put(e1));
    }
  }

private:
  EtchCircularQueue* mQueue;
};

class R2 : public capu::Runnable {
public:
  R2(EtchCircularQueue* queue) {
    mQueue = queue;
  }

  void run() {
    // Consumer
    for(capu::int32_t i = 0; i < 2000; i++) {
      EtchMailbox::EtchElement * e1 = NULL;
      EXPECT_EQ(ETCH_OK, mQueue->get(&e1));
      delete e1;
    }
  }

private:
  EtchCircularQueue* mQueue;
};

}

TEST(EtchCirclerQueueTest, concurrency) {
  EtchCircularQueue* queue = new EtchCircularQueue(5);

  R1* r1 = new R1(queue);
  capu::Thread* t1 = new capu::Thread(r1);
  t1->start();

  R2* r2 = new R2(queue);
  capu::Thread* t2 = new capu::Thread(r2);
  t2->start();

  t1->join();
  t2->join();

  delete r1;
  delete r2;
  delete t1;
  delete t2;
  delete queue;
}
