/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed 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 <termios.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

#include <deque>
#include <thread>
#include <vector>

#include <gflags/gflags.h>
#include <android-base/logging.h>

#include <common/libs/fs/shared_fd.h>
#include <common/libs/fs/shared_select.h>
#include <host/libs/config/cuttlefish_config.h>
#include <host/libs/config/logging.h>

DEFINE_int32(console_in_fd,
             -1,
             "File descriptor for the console's input channel");
DEFINE_int32(console_out_fd,
             -1,
             "File descriptor for the console's output channel");

namespace cuttlefish {

// Handles forwarding the serial console to a pseudo-terminal (PTY)
// It receives a couple of fds for the console (could be the same fd twice if,
// for example a socket_pair were used).
// Data available in the console's output needs to be read immediately to avoid
// the having the VMM blocked on writes to the pipe. To achieve this one thread
// takes care of (and only of) all read calls (from console output and from the
// socket client), using select(2) to ensure it never blocks. Writes are handled
// in a different thread, the two threads communicate through a buffer queue
// protected by a mutex.
class ConsoleForwarder {
 public:
  ConsoleForwarder(std::string console_path, SharedFD console_in,
                   SharedFD console_out, SharedFD console_log)
      : console_path_(console_path),
        console_in_(console_in),
        console_out_(console_out),
        console_log_(console_log) {}
  [[noreturn]] void StartServer() {
    // Create a new thread to handle writes to the console
    writer_thread_ = std::thread([this]() { WriteLoop(); });
    // Use the calling thread (likely the process' main thread) to handle
    // reading the console's output and input from the client.
    ReadLoop();
  }
 private:
  SharedFD OpenPTY() {
    // Remove any stale symlink to a pts device
    auto ret = unlink(console_path_.c_str());
    CHECK(!(ret < 0 && errno != ENOENT))
        << "Failed to unlink " << console_path_ << ": " << strerror(errno);

    auto pty = posix_openpt(O_RDWR | O_NOCTTY | O_NONBLOCK);
    CHECK(pty >= 0) << "Failed to open a PTY: " << strerror(errno);

    grantpt(pty);
    unlockpt(pty);

    // Disable all echo modes on the PTY
    struct termios termios;
    CHECK(tcgetattr(pty, &termios) >= 0)
        << "Failed to get terminal control: " << strerror(errno);

    termios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
    termios.c_oflag &= ~(ONLCR);
    CHECK(tcsetattr(pty, TCSANOW, &termios) >= 0)
        << "Failed to set terminal control: " << strerror(errno);

    auto pty_dev_name = ptsname(pty);
    CHECK(pty_dev_name != nullptr)
        << "Failed to obtain PTY device name: " << strerror(errno);

    CHECK(symlink(pty_dev_name, console_path_.c_str()) >= 0)
        << "Failed to create symlink to " << pty_dev_name << " at "
        << console_path_ << ": " << strerror(errno);

    auto pty_shared_fd = SharedFD::Dup(pty);
    close(pty);
    CHECK(pty_shared_fd->IsOpen())
        << "Error dupping fd " << pty << ": " << pty_shared_fd->StrError();

    return pty_shared_fd;
  }

  void EnqueueWrite(std::shared_ptr<std::vector<char>> buf_ptr, SharedFD fd) {
    std::lock_guard<std::mutex> lock(write_queue_mutex_);
    write_queue_.emplace_back(fd, buf_ptr);
    condvar_.notify_one();
  }

  [[noreturn]] void WriteLoop() {
    while (true) {
      while (!write_queue_.empty()) {
        std::shared_ptr<std::vector<char>> buf_ptr;
        SharedFD fd;
        {
          std::lock_guard<std::mutex> lock(write_queue_mutex_);
          auto& front = write_queue_.front();
          buf_ptr = front.second;
          fd = front.first;
          write_queue_.pop_front();
        }
        // Write all bytes to the file descriptor. Writes may block, so the
        // mutex lock should NOT be held while writing to avoid blocking the
        // other thread.
        ssize_t bytes_written = 0;
        ssize_t bytes_to_write = buf_ptr->size();
        while (bytes_to_write > 0) {
          bytes_written =
              fd->Write(buf_ptr->data() + bytes_written, bytes_to_write);
          if (bytes_written < 0) {
            // It is expected for writes to the PTY to fail if nothing is connected
            if(fd->GetErrno() != EAGAIN) {
              LOG(ERROR) << "Error writing to fd: " << fd->StrError();
            }

            // Don't try to write from this buffer anymore, error handling will
            // be done on the reading thread (failed client will be
            // disconnected, on serial console failure this process will abort).
            break;
          }
          bytes_to_write -= bytes_written;
        }
      }
      {
        std::unique_lock<std::mutex> lock(write_queue_mutex_);
        // Check again before sleeping, state may have changed
        if (write_queue_.empty()) {
          condvar_.wait(lock);
        }
      }
    }
  }

  [[noreturn]] void ReadLoop() {
    SharedFD client_fd;
    while (true) {
      if (!client_fd->IsOpen()) {
        client_fd = OpenPTY();
      }

      SharedFDSet read_set;
      read_set.Set(console_out_);
      read_set.Set(client_fd);

      Select(&read_set, nullptr, nullptr, nullptr);
      if (read_set.IsSet(console_out_)) {
        std::shared_ptr<std::vector<char>> buf_ptr = std::make_shared<std::vector<char>>(4096);
        auto bytes_read = console_out_->Read(buf_ptr->data(), buf_ptr->size());
        // This is likely unrecoverable, so exit here
        CHECK(bytes_read > 0) << "Error reading from console output: "
                              << console_out_->StrError();
        buf_ptr->resize(bytes_read);
        EnqueueWrite(buf_ptr, console_log_);
        if (client_fd->IsOpen()) {
          EnqueueWrite(buf_ptr, client_fd);
        }
      }
      if (read_set.IsSet(client_fd)) {
        std::shared_ptr<std::vector<char>> buf_ptr = std::make_shared<std::vector<char>>(4096);
        auto bytes_read = client_fd->Read(buf_ptr->data(), buf_ptr->size());
        if (bytes_read <= 0) {
          // If this happens, it's usually because the PTY controller went away
          // e.g. the user closed minicom, or killed screen, or closed kgdb. In
          // such a case, we will just re-create the PTY
          LOG(ERROR) << "Error reading from client fd: "
                     << client_fd->StrError();
          client_fd->Close();
        } else {
          buf_ptr->resize(bytes_read);
          EnqueueWrite(buf_ptr, console_in_);
        }
      }
    }
  }

  std::string console_path_;
  SharedFD console_in_;
  SharedFD console_out_;
  SharedFD console_log_;
  std::thread writer_thread_;
  std::mutex write_queue_mutex_;
  std::condition_variable condvar_;
  std::deque<std::pair<SharedFD, std::shared_ptr<std::vector<char>>>>
      write_queue_;
};

int ConsoleForwarderMain(int argc, char** argv) {
  DefaultSubprocessLogging(argv);
  ::gflags::ParseCommandLineFlags(&argc, &argv, true);

  CHECK(!(FLAGS_console_in_fd < 0 || FLAGS_console_out_fd < 0))
      << "Invalid file descriptors: " << FLAGS_console_in_fd << ", "
      << FLAGS_console_out_fd;

  auto console_in = SharedFD::Dup(FLAGS_console_in_fd);
  CHECK(console_in->IsOpen()) << "Error dupping fd " << FLAGS_console_in_fd
                              << ": " << console_in->StrError();
  close(FLAGS_console_in_fd);

  auto console_out = SharedFD::Dup(FLAGS_console_out_fd);
  CHECK(console_out->IsOpen()) << "Error dupping fd " << FLAGS_console_out_fd
                               << ": " << console_out->StrError();
  close(FLAGS_console_out_fd);

  auto config = CuttlefishConfig::Get();
  CHECK(config) << "Unable to get config object";

  auto instance = config->ForDefaultInstance();
  auto console_path = instance.console_path();
  auto console_log = instance.PerInstancePath("console_log");
  auto console_log_fd =
      SharedFD::Open(console_log.c_str(), O_CREAT | O_APPEND | O_WRONLY, 0666);
  ConsoleForwarder console_forwarder(console_path, console_in, console_out, console_log_fd);

  // Don't get a SIGPIPE from the clients
  CHECK(sigaction(SIGPIPE, nullptr, nullptr) == 0)
      << "Failed to set SIGPIPE to be ignored: " << strerror(errno);

  console_forwarder.StartServer();
}

}  // namespace cuttlefish

int main(int argc, char** argv) {
  return cuttlefish::ConsoleForwarderMain(argc, argv);
}
