// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/macros.h"
#include "base/run_loop.h"
#include "base/task/single_thread_task_executor.h"
#include "build/build_config.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_sync_channel.h"
#include "native_client/src/untrusted/irt/irt_dev.h"
#include "ppapi/nacl_irt/irt_interfaces.h"
#include "ppapi/nacl_irt/plugin_startup.h"
#include "ppapi/proxy/ppapi_messages.h"

#if !defined(OS_NACL_NONSFI)

namespace {

class TranslatorCompileListener : public IPC::Listener {
 public:
  TranslatorCompileListener(const IPC::ChannelHandle& handle,
                            const struct nacl_irt_pnacl_compile_funcs* funcs)
      : funcs_(funcs) {
    channel_ = IPC::Channel::Create(handle, IPC::Channel::MODE_SERVER, this);
    CHECK(channel_->Connect());
  }

  // Needed for handling sync messages in OnMessageReceived().
  bool Send(IPC::Message* message) {
    return channel_->Send(message);
  }

  virtual bool OnMessageReceived(const IPC::Message& msg) {
    bool handled = false;
    IPC_BEGIN_MESSAGE_MAP(TranslatorCompileListener, msg)
      IPC_MESSAGE_HANDLER_DELAY_REPLY(PpapiMsg_PnaclTranslatorCompileInit,
                                      OnPnaclTranslatorCompileInit)
      IPC_MESSAGE_HANDLER_DELAY_REPLY(PpapiMsg_PnaclTranslatorCompileChunk,
                                      OnPnaclTranslatorCompileChunk)
      IPC_MESSAGE_HANDLER_DELAY_REPLY(PpapiMsg_PnaclTranslatorCompileEnd,
                                      OnPnaclTranslatorCompileEnd)
      IPC_MESSAGE_UNHANDLED(handled = false)
    IPC_END_MESSAGE_MAP()
    return handled;
  }

 private:
  void OnPnaclTranslatorCompileInit(
      int num_threads,
      const std::vector<ppapi::proxy::SerializedHandle>& obj_files,
      const std::vector<std::string>& cmd_flags,
      IPC::Message* reply_msg) {
    std::vector<int> obj_file_fds(obj_files.size());
    for (size_t i = 0; i < obj_files.size(); ++i) {
      CHECK(obj_files[i].is_file());
      obj_file_fds[i] = obj_files[i].descriptor().fd;
    }

    std::vector<char*> cmd_flags_cstrings(cmd_flags.size());
    for (size_t i = 0; i < cmd_flags.size(); ++i) {
      // It's OK to use const_cast here because the callee (the translator)
      // is not supposed to modify the strings.  (The interface definition
      // should have used "const char* const*".)
      cmd_flags_cstrings[i] = const_cast<char*>(cmd_flags[i].c_str());
    }

    char* error_cstr = funcs_->init_callback(num_threads,
                                             obj_file_fds.data(),
                                             obj_file_fds.size(),
                                             cmd_flags_cstrings.data(),
                                             cmd_flags_cstrings.size());
    bool success = !error_cstr;
    std::string error_str(error_cstr ? error_cstr : "");
    PpapiMsg_PnaclTranslatorCompileInit::WriteReplyParams(
        reply_msg, success, error_str);
    Send(reply_msg);
  }

  void OnPnaclTranslatorCompileChunk(const std::string& data_chunk,
                                     IPC::Message* reply_msg) {
    int result = funcs_->data_callback(data_chunk.data(), data_chunk.size());
    bool success = !result;
    PpapiMsg_PnaclTranslatorCompileChunk::WriteReplyParams(reply_msg, success);
    Send(reply_msg);
  }

  void OnPnaclTranslatorCompileEnd(IPC::Message* reply_msg) {
    char* error_cstr = funcs_->end_callback();
    bool success = !error_cstr;
    std::string error_str(error_cstr ? error_cstr : "");
    PpapiMsg_PnaclTranslatorCompileEnd::WriteReplyParams(
        reply_msg, success, error_str);
    Send(reply_msg);
  }

  std::unique_ptr<IPC::Channel> channel_;
  const struct nacl_irt_pnacl_compile_funcs* funcs_;

  DISALLOW_COPY_AND_ASSIGN(TranslatorCompileListener);
};

void ServeTranslateRequest(const struct nacl_irt_pnacl_compile_funcs* funcs) {
  base::SingleThreadTaskExecutor main_task_executor;
  new TranslatorCompileListener(ppapi::GetRendererIPCChannelHandle(), funcs);
  base::RunLoop().Run();
}

}

const struct nacl_irt_private_pnacl_translator_compile
    nacl_irt_private_pnacl_translator_compile = {
  ServeTranslateRequest
};

#endif  // !defined(OS_NACL_NONSFI)
