/* $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 <gmock/gmock.h>
#include "support/EtchRemoteBase.h"
#include "transport/EtchDefaultDeliveryService.h"
#include "serialization/EtchDefaultValueFactory.h"
#include "support/EtchPlainMailbox.h"
#include "transport/EtchPlainMailboxManager.h"
#include "support/EtchRuntime.h"

class MockSession2 : public EtchSessionMessage {
public:

  status_t sessionMessage(capu::SmartPointer<EtchWho> receipent, capu::SmartPointer<EtchMessage> buf) {
    return ETCH_OK;
  }

  status_t sessionQuery(capu::SmartPointer<EtchObject> query, capu::SmartPointer<EtchObject> &result) {
    return ETCH_OK;
  }

  status_t sessionControl(capu::SmartPointer<EtchObject> control, capu::SmartPointer<EtchObject> value) {
    return ETCH_OK;
  }

  status_t sessionNotify(capu::SmartPointer<EtchObject> event) {
    return ETCH_OK;
  }
};

class MockTransport2 : public EtchTransportMessage {
public:

  status_t transportMessage(capu::SmartPointer<EtchWho> recipient, capu::SmartPointer<EtchMessage> message) {
    return ETCH_OK;
  }

  MOCK_METHOD0(getSession, EtchSessionMessage* ());

  void setSession(EtchSessionMessage* session) {

  }

  status_t transportQuery(capu::SmartPointer<EtchObject> query, capu::SmartPointer<EtchObject> *result) {
    return ETCH_OK;
  }

  status_t transportControl(capu::SmartPointer<EtchObject> control, capu::SmartPointer<EtchObject> value) {
    return ETCH_OK;
  }

  status_t transportNotify(capu::SmartPointer<EtchObject> event) {
    return ETCH_OK;
  }
};

class MockDefaultValueFactory2 {
public:
  EtchTypeMap types;
  EtchClass2TypeMap class2type;
  EtchDefaultValueFactory * factory;

  /**
   * Constructs the MyValueFactory.
   * @param uri
   */
public:

  MockDefaultValueFactory2(EtchString uri) {
    EtchDefaultValueFactory::Init(&types, &class2type);
    factory = new EtchDefaultValueFactory(uri, &types, &class2type);
  }

  ~MockDefaultValueFactory2() {
    delete factory;
    types.clear();
  }
};

class EtchRemoteBaseTest
  : public ::testing::Test {
protected:
  virtual void SetUp() {
    mRuntime = new EtchRuntime();
    mRuntime->setLogger(new EtchLogger());
    mRuntime->start();
  }

  virtual void TearDown() {
    mRuntime->shutdown();
    EtchLogger* logger = mRuntime->getLogger();
    if(logger != NULL) {
      delete logger;
    }
    delete mRuntime;
    mRuntime = NULL;
  }

  EtchRuntime* mRuntime;
};

TEST_F(EtchRemoteBaseTest, constructorTest) {
  MockSession2 session;
  MockTransport2 *transport = new MockTransport2();
  MockDefaultValueFactory2 *factory;
  EtchString uri("tcp://127.0.0.1:4001");
  factory = new MockDefaultValueFactory2(uri);
  //created value factory
  EtchURL u(uri);
  EtchPlainMailboxManager * manager = NULL;
  manager = new EtchPlainMailboxManager(transport, NULL, NULL);
  EtchDeliveryService * service = NULL;
  service = new EtchDefaultDeliveryService(manager, &u);
  EtchRemoteBase * remote = NULL;
  remote = new EtchRemoteBase(service, factory->factory);

  EXPECT_TRUE(remote != NULL);
  manager->setSession(service);
  service->setSession(&session);

  delete remote;
  delete service;
  delete factory;
}

TEST_F(EtchRemoteBaseTest, newMessageTest) {
  MockSession2 session;
  MockTransport2 *transport = new MockTransport2();
  MockDefaultValueFactory2 *factory;
  EtchString uri("tcp://127.0.0.1:4001");
  factory = new MockDefaultValueFactory2(uri);
  //created value factory
  EtchURL u(uri);

  EtchPlainMailboxManager * manager = NULL;
  manager = new EtchPlainMailboxManager(transport, NULL, NULL);
  EtchDeliveryService * service = NULL;
  service = new EtchDefaultDeliveryService(manager, &u);
  EtchRemoteBase * remote = NULL;
  remote = new EtchRemoteBase(service, factory->factory);

  EXPECT_TRUE(remote != NULL);
  manager->setSession(service);
  service->setSession(&session);

  //create type
  EtchString typeName("foo");
  EtchType mt(typeName);
  //create new message
  capu::SmartPointer<EtchMessage> msg;
  remote->newMessage(&mt, &msg);

  //check type
  EXPECT_TRUE(msg->isType(&mt));

  //check the assigned factory
  EXPECT_TRUE(factory->factory == msg->getValueFactory());

  delete remote;
  delete service;
  delete factory;
}

TEST_F(EtchRemoteBaseTest, sendTest) {
  MockSession2 session;
  MockTransport2 *transport = new MockTransport2();
  MockDefaultValueFactory2 *factory;
  EtchString uri("tcp://127.0.0.1:4001");
  factory = new MockDefaultValueFactory2(uri);
  //created value factory
  EtchURL u(uri);

  EtchPlainMailboxManager * manager = NULL;
  manager = new EtchPlainMailboxManager(transport, NULL, NULL);
  EtchDeliveryService * service = NULL;
  service = new EtchDefaultDeliveryService(manager, &u);
  EtchRemoteBase * remote = NULL;
  remote = new EtchRemoteBase(service, factory->factory);

  EXPECT_TRUE(remote != NULL);
  manager->setSession(service);
  service->setSession(&session);

  //get the validator
  capu::SmartPointer<EtchValidator> val = NULL;
  EtchValidatorLong::Get(0, val);
  //create type
  EtchType *mt;
  factory->types.get("add", mt);
  mt->putValidator(EtchDefaultValueFactory::_mf__messageId(), val);
  //create new message
  capu::SmartPointer<EtchMessage> msg;
  remote->newMessage(mt, &msg);

  //check type
  EXPECT_TRUE(msg->isType(mt));
  //remote send
  EXPECT_TRUE(remote->send(msg) == ETCH_OK);

  factory->types.clear();
  delete remote;
  delete service;
  delete factory;
}

TEST_F(EtchRemoteBaseTest, beginCallTest) {
  MockSession2 session;
  MockTransport2 *transport = new MockTransport2();
  MockDefaultValueFactory2 *factory;
  EtchString uri("tcp://127.0.0.1:4001");
  factory = new MockDefaultValueFactory2(uri);
  //created value factory
  EtchURL u(uri);

  EtchPlainMailboxManager * manager = NULL;
  manager = new EtchPlainMailboxManager(transport, NULL, NULL);
  EtchDeliveryService * service = NULL;
  service = new EtchDefaultDeliveryService(manager, &u);
  EtchRemoteBase * remote = NULL;
  remote = new EtchRemoteBase(service, factory->factory);

  EXPECT_TRUE(remote != NULL);
  manager->setSession(service);
  service->setSession(&session);

  //get the validator
  capu::SmartPointer<EtchValidator> val = NULL;
  EtchValidatorLong::Get(0, val);
  //create type
  EtchType *mt;
  factory->types.get("add", mt);
  mt->putValidator(EtchDefaultValueFactory::_mf__messageId(), val);

  //create new message
  capu::SmartPointer<EtchMessage> msg;
  remote->newMessage(mt, &msg);

  //check type
  EXPECT_TRUE(msg->isType(mt));

  manager->sessionNotify(new EtchString(EtchSession::UP()));

  EtchMailbox *mail = NULL;
  EXPECT_TRUE(remote->begincall(msg, mail) == ETCH_OK);
  EXPECT_TRUE(mail != NULL);

  factory->types.clear();
  delete remote;
  delete service;
  delete factory;
}

TEST_F(EtchRemoteBaseTest, endCallTest) {
  MockSession2 session;
  MockTransport2 *transport = new MockTransport2();
  MockDefaultValueFactory2 *factory;
  EtchString uri("tcp://127.0.0.1:4001");
  factory = new MockDefaultValueFactory2(uri);
  //created value factory
  EtchURL u(uri);

  EtchPlainMailboxManager * manager = NULL;
  manager = new EtchPlainMailboxManager(transport, NULL, NULL);
  EtchDeliveryService * service = NULL;
  service = new EtchDefaultDeliveryService(manager, &u);
  EtchRemoteBase * remote = NULL;
  remote = new EtchRemoteBase(service, factory->factory);

  EXPECT_TRUE(remote != NULL);
  manager->setSession(service);
  service->setSession(&session);

  //create type
  EtchType * type;
  EtchType * replyType;
  capu::SmartPointer<EtchValidator> val = NULL;
  EtchValidatorLong::Get(0, val);

  factory->types.get("add_result", replyType);
  factory->types.get("add", type);
  type->putValidator(EtchDefaultValueFactory::_mf__messageId(), val);
  replyType->putValidator(EtchDefaultValueFactory::_mf__inReplyTo(), val);
  replyType->putValidator(EtchDefaultValueFactory::_mf__messageId(), val);
  replyType->putValidator(EtchDefaultValueFactory::_mf_result(), val);
  replyType->setResponseField(EtchDefaultValueFactory::_mf_result());

  //create new message
  capu::SmartPointer<EtchMessage> replyMessage;
  capu::SmartPointer<EtchMessage> message;
  remote->newMessage(type, &message);

  manager->sessionNotify(new EtchString(EtchSession::UP()));

  EtchMailbox *mail = NULL;
  EXPECT_TRUE(remote->begincall(message, mail) == ETCH_OK);

  EXPECT_TRUE(mail != NULL);

  capu::int64_t id;
  message->getMessageId(id);
  //create a reply message
  message->createReplyMessage(replyType, replyMessage);
  EXPECT_TRUE(ETCH_OK == replyMessage->getInReplyToMessageId(id));
  capu::SmartPointer<EtchMessage> replymess = replyMessage;
  capu::SmartPointer<EtchObject> data = new EtchLong(123);
  capu::SmartPointer<EtchObject> old;
  EtchField field = replyType->getResponseField();
  replyMessage->put(field, data, &old);
  //call the sessionMessage of mailbox manager as if it is called from messagizer to deliver data from
  EXPECT_TRUE(ETCH_OK == manager->sessionMessage(NULL, replymess));
  capu::SmartPointer<EtchObject> result;
  EXPECT_TRUE(remote->endcall(mail, replyType, result) == ETCH_OK);
  EXPECT_TRUE(mail != NULL);
  EXPECT_TRUE(result == data);

  factory->types.clear();
  delete mail;
  delete remote;
  delete service;
  delete factory;
}
