// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


#ifdef OS_WIN
// Do not change the order of the following headers required for Windows.
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
#define ssize_t SSIZE_T
#else
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#endif  // OS_WIN

#include <cstddef>
#include <cstring>
#include <vector>
#include <string>

#include "base/number_util.h"
#include "base/singleton.h"
#include "base/scoped_ptr.h"
#include "base/system_util.h"
#include "engine/engine_factory.h"
#include "session/commands.pb.h"
#include "session/random_keyevents_generator.h"
#include "session/session_handler.h"
#include "session/session_usage_observer.h"

DEFINE_string(host, "localhost", "server host name");
DEFINE_bool(server, true, "server mode");
DEFINE_bool(client, false, "client mode");
DEFINE_int32(client_test_size, 100, "client test size");
DEFINE_int32(port, 8000, "port of RPC server");
DEFINE_int32(rpc_timeout, 60000, "timeout");
DEFINE_string(user_profile_directory, "", "user profile directory");

namespace mozc {

namespace {

const size_t kMaxRequestSize = 32 * 32 * 8192;
const size_t kMaxOutputSize  = 32 * 32 * 8192;
const int    kInvalidSocket  = -1;

// TODO(taku): timeout should be handled.
bool Recv(int socket, char *buf,
          size_t buf_size, int timeout) {
  ssize_t buf_left = buf_size;
  while (buf_left > 0) {
    const ssize_t read_size = ::recv(socket, buf, buf_left, 0);
    if (read_size < 0) {
      LOG(ERROR) << "an error occurred during recv()";
      return false;
    }
    buf += read_size;
    buf_left -= read_size;
  }
  return buf_left == 0;
}

// TODO(taku): timeout should be handled.
bool Send(int socket, const char *buf,
          size_t buf_size, int timeout) {
  ssize_t buf_left = buf_size;
  while (buf_left > 0) {
#if defined(OS_WIN)
    const int kFlag = 0;
#elif defined(OS_MACOSX)
    const int kFlag = SO_NOSIGPIPE;
#else
    const int kFlag = MSG_NOSIGNAL;
#endif
    const ssize_t read_size = ::send(socket, buf, buf_left, kFlag);
    if (read_size < 0) {
      LOG(ERROR) << "an error occurred during sending";
      return false;
    }
    buf += read_size;
    buf_left -= read_size;
  }
  return buf_left == 0;
}

void CloseSocket(int client_socket) {
#ifdef OS_WIN
  ::closesocket(client_socket);
  ::shutdown(client_socket, SD_BOTH);
#else
  ::close(client_socket);
  ::shutdown(client_socket, SHUT_RDWR);
#endif
}

// Standalone RPCServer.
// TODO(taku): Make a RPC class inherited from IPCInterface.
// This allows us to reuse client::Session library and SessionServer.
class RPCServer {
 public:
  RPCServer() : server_socket_(kInvalidSocket),
                engine_(EngineFactory::Create()),
                handler_(new SessionHandler(engine_.get())) {
    struct sockaddr_in sin;

    server_socket_ = ::socket(AF_INET, SOCK_STREAM, 0);

    CHECK_NE(server_socket_, kInvalidSocket) << "socket failed";

#ifndef OS_WIN
    int flags = ::fcntl(server_socket_, F_GETFD, 0);
    CHECK_GE(flags, 0) << "fcntl(F_GETFD) failed";
    flags |= FD_CLOEXEC;
    CHECK_EQ(::fcntl(server_socket_, F_SETFD, flags), 0)
        << "fctl(F_SETFD) failed";
#endif

    ::memset(&sin, 0, sizeof(sin));
    sin.sin_port = htons(FLAGS_port);
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = htonl(INADDR_ANY);

    int on = 1;
    ::setsockopt(server_socket_,
                 SOL_SOCKET,
                 SO_REUSEADDR, reinterpret_cast<char * >(&on),
                 sizeof(on));

    CHECK_GE(::bind(server_socket_,
                    reinterpret_cast<struct sockaddr *>(&sin),
                    sizeof(sin)), 0) << "bind failed";

    CHECK_GE(::listen(server_socket_, SOMAXCONN), 0) << "listen failed";
    CHECK_NE(server_socket_, 0);

    handler_->AddObserver(Singleton<session::SessionUsageObserver>::get());
  }

  ~RPCServer() {
    CloseSocket(server_socket_);
    server_socket_ = kInvalidSocket;
  }

  void Loop() {
    LOG(INFO) << "Start Mozc RPCServer";

    while (true) {
      const int client_socket = ::accept(server_socket_, NULL, NULL);

      if (client_socket == kInvalidSocket) {
        LOG(ERROR) << "accept failed";
        continue;
      }

      uint32 request_size = 0;
      // Receive the size of data.
      if (!Recv(client_socket, reinterpret_cast<char *>(&request_size),
                sizeof(request_size), FLAGS_rpc_timeout)) {
        LOG(ERROR) << "Cannot receive request_size header.";
        CloseSocket(client_socket);
        continue;
      }
      request_size = ntohl(request_size);
      CHECK_GT(request_size, 0);
      CHECK_LT(request_size, kMaxRequestSize);

      // Receive the body of serialized protobuf.
      scoped_ptr<char[]> request_str(new char[request_size]);
      if (!Recv(client_socket,
                request_str.get(), request_size, FLAGS_rpc_timeout)) {
        LOG(ERROR) << "cannot receive body of request.";
        CloseSocket(client_socket);
        continue;
      }

      commands::Command command;
      if (!command.mutable_input()->ParseFromArray(request_str.get(),
                                                   request_size)) {
        LOG(ERROR) << "ParseFromArray failed";
        CloseSocket(client_socket);
        continue;
      }

      CHECK(handler_->EvalCommand(&command));

      string output_str;
      // Return the result.
      CHECK(command.output().SerializeToString(&output_str));

      uint32 output_size = output_str.size();
      CHECK_GT(output_size, 0);
      CHECK_LT(output_size, kMaxOutputSize);
      output_size = htonl(output_size);

      if (!Send(client_socket, reinterpret_cast<char *>(&output_size),
                sizeof(output_size), FLAGS_rpc_timeout) ||
          !Send(client_socket, output_str.data(), output_str.size(),
                FLAGS_rpc_timeout)) {
        LOG(ERROR) << "Cannot send reply.";
      }

      CloseSocket(client_socket);
    }
  }

 private:
  int server_socket_;
  scoped_ptr<EngineInterface> engine_;
  scoped_ptr<SessionHandler> handler_;
};

// Standalone RPCClient.
// TODO(taku): Make a RPC class inherited from IPCInterface.
// This allows us to reuse client::Session library and SessionServer.
class RPCClient {
 public:
  RPCClient() : id_(0) {}

  bool CreateSession() {
    id_ = 0;
    commands::Input input;
    commands::Output output;
    input.set_type(commands::Input::CREATE_SESSION);
    if (!Call(input, &output) ||
        output.error_code() != commands::Output::SESSION_SUCCESS) {
      return false;
    }
    id_ = output.id();
    return true;
  }

  bool DeleteSession() {
    commands::Input input;
    commands::Output output;
    id_ = 0;
    input.set_type(commands::Input::DELETE_SESSION);
    return (Call(input, &output) &&
            output.error_code() == commands::Output::SESSION_SUCCESS);
  }

  bool SendKey(const mozc::commands::KeyEvent &key,
               mozc::commands::Output *output) const {
    if (id_ == 0) {
      return false;
    }
    commands::Input input;
    input.set_type(commands::Input::SEND_KEY);
    input.set_id(id_);
    input.mutable_key()->CopyFrom(key);
    return (Call(input, output) &&
            output->error_code() == commands::Output::SESSION_SUCCESS);
  }

 private:
  bool Call(const commands::Input &input,
            commands::Output *output) const {
    struct addrinfo hints, *res;
    ::memset(&hints, 0, sizeof(hints));
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_family = AF_INET;

    const string port_str = NumberUtil::SimpleItoa(FLAGS_port);
    CHECK_EQ(::getaddrinfo(FLAGS_host.c_str(), port_str.c_str(),
                           &hints, &res), 0)
        << "getaddrinfo failed";

    const int client_socket = ::socket(res->ai_family,
                                       res->ai_socktype,
                                       res->ai_protocol);
    CHECK_NE(client_socket, kInvalidSocket) << "socket failed";
    CHECK_GE(::connect(client_socket,
                       res->ai_addr, res->ai_addrlen), 0)
        << "connect failed";

    string request_str;
    CHECK(input.SerializeToString(&request_str));
    uint32 request_size = request_str.size();
    CHECK_GT(request_size, 0);
    CHECK_LT(request_size, kMaxRequestSize);
    request_size = htonl(request_size);

    CHECK(Send(client_socket, reinterpret_cast<char *>(&request_size),
               sizeof(request_size), FLAGS_rpc_timeout));
    CHECK(Send(client_socket, request_str.data(), request_str.size(),
               FLAGS_rpc_timeout));

    uint32 output_size = 0;
    CHECK(Recv(client_socket, reinterpret_cast<char *>(&output_size),
               sizeof(output_size), FLAGS_rpc_timeout));
    output_size = ntohl(output_size);
    CHECK_GT(output_size, 0);
    CHECK_LT(output_size, kMaxOutputSize);

    scoped_ptr<char[]> output_str(new char[output_size]);
    CHECK(Recv(client_socket,
               output_str.get(), output_size, FLAGS_rpc_timeout));

    CHECK(output->ParseFromArray(output_str.get(), output_size));

    ::freeaddrinfo(res);

    CloseSocket(client_socket);

    return true;
  }

  uint64 id_;
};

// Wrapper class for WSAStartup on Windows.
class ScopedWSAData {
 public:
  ScopedWSAData() {
#ifdef OS_WIN
    WSADATA wsaData;
    CHECK_EQ(::WSAStartup(MAKEWORD(2, 1), &wsaData), 0)
        << "WSAStartup failed";
#endif
  }
  ~ScopedWSAData() {
#ifdef OS_WIN
    ::WSACleanup();
#endif
  }
};
}  // namespace

}  // namespace mozc

int main(int argc, char *argv[]) {
  InitGoogle(argv[0], &argc, &argv, false);

  mozc::ScopedWSAData wsadata;

  if (!FLAGS_user_profile_directory.empty()) {
    LOG(INFO) << "Setting user profile directory to "
              << FLAGS_user_profile_directory;
    mozc::SystemUtil::SetUserProfileDirectory(FLAGS_user_profile_directory);
  }

  if (FLAGS_client) {
    mozc::RPCClient client;
    CHECK(client.CreateSession());
    for (int n = 0; n < FLAGS_client_test_size; ++n) {
      vector<mozc::commands::KeyEvent> keys;
      mozc::session::RandomKeyEventsGenerator::GenerateSequence(&keys);
      for (size_t i = 0; i < keys.size(); ++i) {
        LOG(INFO) << "Sending to Server: " << keys[i].Utf8DebugString();
        mozc::commands::Output output;
        CHECK(client.SendKey(keys[i], &output));
        LOG(INFO) << "Output of SendKey: " << output.Utf8DebugString();
      }
    }
    CHECK(client.DeleteSession());
    return 0;
  } else if (FLAGS_server) {
    mozc::RPCServer server;
    server.Loop();
  } else {
    LOG(ERROR) << "use --server or --client option";
    return -1;
  }

  return 0;
}
