// This autogenerated skeleton file illustrates how to build a server.
// You should copy it to another filename to avoid overwriting it.

#include "ThreadsTest.h"
#include <protocol/TBinaryProtocol.h>
#include <server/TThreadPoolServer.h>
#include <transport/TServerSocket.h>
#include <transport/TTransportUtils.h>
#include <thrift/concurrency/Monitor.h>
#include <thrift/concurrency/ThreadManager.h>
#include <thrift/concurrency/PosixThreadFactory.h>

using namespace facebook::thrift;
using namespace facebook::thrift::protocol;
using namespace facebook::thrift::transport;
using namespace facebook::thrift::server;
using namespace facebook::thrift::concurrency;


class ThreadsTestHandler : virtual public ThreadsTestIf {
 public:
  ThreadsTestHandler() {
    // Your initialization goes here
  }

  void threadOne(const int32_t sleep) {
    // Your implementation goes here
    printf("threadOne\n");
    go2sleep(1, sleep);
  }

  void threadTwo(const int32_t sleep) {
    // Your implementation goes here
    printf("threadTwo\n");
    go2sleep(2, sleep);
  }

  void threadThree(const int32_t sleep) {
    // Your implementation goes here
    printf("threadThree\n");
    go2sleep(3, sleep);
  }

  void threadFour(const int32_t sleep) {
    // Your implementation goes here
    printf("threadFour\n");
    go2sleep(4, sleep);
  }

  void stop() {
    printf("stop\n");
    server_->stop();
  }

  void setServer(boost::shared_ptr<TServer> server) {
    server_ = server;
  }

protected:
  void go2sleep(int thread, int seconds) {
    Monitor m;
    for (int i = 0; i < seconds; ++i) {
      fprintf(stderr, "Thread %d: sleep %d\n", thread, i);
      m.wait(1000);
    }
    fprintf(stderr, "THREAD %d DONE\n", thread);
  }

private:
  boost::shared_ptr<TServer> server_;

};

int main(int argc, char **argv) {
  int port = 9090;
  shared_ptr<ThreadsTestHandler> handler(new ThreadsTestHandler());
  shared_ptr<TProcessor> processor(new ThreadsTestProcessor(handler));
  shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
  shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
  shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());

  shared_ptr<ThreadManager> threadManager = 
    ThreadManager::newSimpleThreadManager(10);
  shared_ptr<PosixThreadFactory> threadFactory =
    shared_ptr<PosixThreadFactory>(new PosixThreadFactory());
  threadManager->threadFactory(threadFactory);
  threadManager->start();
  
  shared_ptr<TServer> threadPoolServer =
    shared_ptr<TServer>(new TThreadPoolServer(processor,
                                              serverTransport,
                                              transportFactory,
                                              protocolFactory,
                                              threadManager));

  handler->setServer(threadPoolServer);

  threadPoolServer->serve();

  fprintf(stderr, "done.\n");

  return 0;
}

