// 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.

#include "ipc/ipc.h"

#include <cstring>
#include <iostream>  // NOLINT
#include <string>
#include <vector>

#include "base/flags.h"
#include "base/logging.h"
#include "base/port.h"
#include "base/thread.h"

DEFINE_string(server_address, "ipc_test", "");
DEFINE_bool(test, false, "automatic test mode");
DEFINE_bool(server, false, "invoke as server mode");
DEFINE_bool(client, false, "invoke as client mode");
DEFINE_string(server_path, "", "server path");
DEFINE_int32(num_threads, 10, "number of threads");
DEFINE_int32(num_requests, 100, "number of requests");

namespace mozc {

class MultiConnections: public Thread {
 public:
  void Run() {
    char buf[8192];
    for (int i = 0; i < FLAGS_num_requests; ++i) {
      mozc::IPCClient con(FLAGS_server_address, FLAGS_server_path);
      CHECK(con.Connected());
      string input = "testtesttesttest";
      size_t length = sizeof(buf);
      ::memset(buf, 0, length);
      CHECK(con.Call(input.data(), input.size(), buf, &length, 1000));
      string output(buf, length);
      CHECK_EQ(input.size(), output.size());
      CHECK_EQ(input, output);
    }
  }
};

class EchoServer: public IPCServer {
 public:
  EchoServer(const string &path,
             int32 num_connections,
             int32 timeout) :
      IPCServer(path, num_connections, timeout) {}
  virtual bool Process(const char *input_buffer,
                       size_t input_length,
                       char *output_buffer,
                       size_t *output_length) {
    ::memcpy(output_buffer, input_buffer, input_length);
    *output_length = input_length;
    return ::memcmp("kill", input_buffer, 4) != 0;
  }
};

class EchoServerThread: public Thread {
 public:
  explicit EchoServerThread(EchoServer *con): con_(con) {}
  virtual void Run() {
    con_->Loop();
  }
 private:
  EchoServer *con_;
};

}  // namespace mozc

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

  if (FLAGS_test) {
    mozc::EchoServer con(FLAGS_server_address, 10, 1000);
    mozc::EchoServerThread server_thread_main(&con);
    server_thread_main.SetJoinable(true);
    server_thread_main.Start();

    vector<mozc::MultiConnections> cons(FLAGS_num_threads);
    for (size_t i = 0; i < cons.size(); ++i) {
      cons[i].SetJoinable(true);
      cons[i].Start();
    }
    for (size_t i = 0; i < cons.size(); ++i) {
      cons[i].Join();
    }

    mozc::IPCClient kill(FLAGS_server_address, FLAGS_server_path);
    const char kill_cmd[32] = "kill";
    char output[32];
    size_t output_size = sizeof(output);
    kill.Call(kill_cmd, strlen(kill_cmd),
              output, &output_size, 1000);
              server_thread_main.Join();

    LOG(INFO) << "Done";

  } else if (FLAGS_server) {
    mozc::EchoServer con(FLAGS_server_address,
                         10, -1);
    CHECK(con.Connected());
    LOG(INFO) << "Start Server at " << FLAGS_server_address;
    con.Loop();
  } else if (FLAGS_client) {
    string line;
    char response[8192];
    while (getline(cin, line)) {
      mozc::IPCClient con(FLAGS_server_address, FLAGS_server_path);
      CHECK(con.Connected());
      size_t response_size = sizeof(response);
      CHECK(con.Call(line.data(), line.size(),
                     response, &response_size, 1000));
      cout << "Request: " << line << endl;
      cout << "Response: " << string(response, response_size) << endl;
    }
  } else {
    LOG(INFO) << "either --server or --client or --test must be set true";
  }

  return 0;
}
