/**
  @section license License

  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 <unistd.h>

#include <stdexcept>
#include <chrono>
#include <utility>
#include <thread>

#include "tsutil/ts_bw_format.h"

#include "shared/rpc/IPCSocketClient.h"
#include "shared/rpc/MessageStorage.h"
#include <tscore/ink_assert.h>
#include <tscore/ink_sock.h>

namespace shared::rpc
{

IPCSocketClient::self_reference
IPCSocketClient::connect(std::chrono::milliseconds wait_ms, int attempts)
{
  std::string text;
  int         err, attempts_remaining{attempts};
  bool        done{false};
  _sock = socket(AF_UNIX, SOCK_STREAM, 0);

  if (this->is_closed()) {
    throw std::runtime_error(swoc::bwprint(text, "connect: error creating new socket. Reason: {}\n", std::strerror(errno)));
  }

  if (safe_fcntl(_sock, F_SETFL, O_NONBLOCK) < 0) {
    this->close();
    throw std::runtime_error(swoc::bwprint(text, "connect: fcntl error. Reason: {}\n", std::strerror(errno)));
  }

  _server.sun_family = AF_UNIX;
  std::strncpy(_server.sun_path, _path.c_str(), sizeof(_server.sun_path) - 1);

  // Very simple connect and retry. We will just try to connect to the Unix Domain
  // Socket and if it tell us to retry we just wait for a few ms and try again for
  // X times.
  do {
    --attempts_remaining;
    if (::connect(_sock, (struct sockaddr *)&_server, sizeof(struct sockaddr_un)) >= 0) {
      done = true;
      break;
    }

    if (errno == EAGAIN || errno == EINPROGRESS || errno == ECONNREFUSED) {
      // Connection cannot be completed immediately
      // EAGAIN for UDS should suffice, but just in case.
      std::this_thread::sleep_for(wait_ms);
      err = errno;
      continue;
    } else {
      // No worth it.
      err = errno;
      break;
    }
  } while (attempts_remaining != 0);

  if ((attempts_remaining == 0 && !done) || !done) {
    this->close();
    errno = err;
    throw std::runtime_error(swoc::bwprint(text, "connect(attempts={}/{}): Couldn't open connection with {}. Last error: {}({})\n",
                                           (attempts - attempts_remaining), attempts, _path, std::strerror(errno), errno));
  }
  return *this;
}

std::int64_t
IPCSocketClient::_safe_write(int fd, const char *buffer, int len)
{
  constexpr int WRITE_READY_TIMEOUT_MS = 1000;

  std::int64_t written{0};
  while (written < len) {
    const ssize_t ret = ::write(fd, buffer + written, len - written);
    if (ret == -1) {
      if (errno == EINTR) {
        continue;
      }
      if (errno == EAGAIN || errno == EWOULDBLOCK) {
        auto const ready = write_ready(fd, WRITE_READY_TIMEOUT_MS);
        if (ready == 1) {
          continue;
        }
        if (ready == 0) {
          errno = ETIMEDOUT;
        }
      }
      return -1;
    }
    if (ret == 0) {
      errno = EIO;
      return -1;
    }
    written += ret;
  }

  return written;
}
IPCSocketClient::self_reference
IPCSocketClient ::send(std::string_view data)
{
  std::string msg{data};
  if (_safe_write(_sock, msg.c_str(), msg.size()) == -1) {
    this->close();
    std::string text;
    throw std::runtime_error{swoc::bwprint(text, "Error writing on stream socket {}({})", std::strerror(errno), errno)};
  }

  return *this;
}

IPCSocketClient::ReadStatus
IPCSocketClient::read_all(std::string &content, std::chrono::milliseconds timeout_ms, int attempts)
{
  if (this->is_closed()) {
    // we had a failure.
    return ReadStatus::UNKNOWN;
  }

  MessageStorage<356000> bs;
  int                    attempts_left{attempts};
  ReadStatus             readStatus{ReadStatus::NO_ERROR};
  // Try to read all the data from the socket. If a timeout happens we retry
  // 'attemps' times. On error we just stop.
  while (attempts_left > 0 || readStatus == ReadStatus::NO_ERROR) {
    auto       buf     = bs.writable_data();
    const auto to_read = bs.available(); // Available in the current memory chunk.
    ssize_t    nread{-1};

    // Try again if timed out.
    if (auto const r = read_ready(_sock, timeout_ms.count()); r == 0) {
      readStatus = ReadStatus::TIMEOUT;
      --attempts_left;
      continue;
    } else if (r < 0) {
      // No more tries.
      readStatus = ReadStatus::READ_ERROR;
      break;
    }

    nread = ::read(_sock, buf, to_read);
    if (nread > 0) {
      bs.save(nread);
      continue;
    } else if (nread == -1) {
      if (errno == EAGAIN || errno == EINTR) {
        continue;
      }
      readStatus = ReadStatus::READ_ERROR;
      break;
    }
    // EOF
    if (bs.stored() > 0) {
      readStatus = ReadStatus::NO_ERROR;
      break;
    }
    readStatus = ReadStatus::READ_ERROR;
    break;
  }
  content = bs.str();
  return readStatus;
}
} // namespace shared::rpc
