// Copyright 2015 The Chromium OS 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 <arpa/inet.h>
#include <map>
#include <memory>
#include <netdb.h>
#include <string>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <utility>

#include <base/bind.h>
#include <base/bind_helpers.h>
#include <base/files/file_util.h>
#include <base/message_loop/message_loop.h>
#include <base/strings/stringprintf.h>
#include <brillo/streams/file_stream.h>
#include <brillo/streams/tls_stream.h>

#include "buffet/socket_stream.h"
#include "buffet/weave_error_conversion.h"

namespace buffet {

using weave::provider::Network;

namespace {

std::string GetIPAddress(const sockaddr* sa) {
  std::string addr;
  char str[INET6_ADDRSTRLEN] = {};
  switch (sa->sa_family) {
    case AF_INET:
      if (inet_ntop(AF_INET,
                    &(reinterpret_cast<const sockaddr_in*>(sa)->sin_addr), str,
                    sizeof(str))) {
        addr = str;
      }
      break;

    case AF_INET6:
      if (inet_ntop(AF_INET6,
                    &(reinterpret_cast<const sockaddr_in6*>(sa)->sin6_addr),
                    str, sizeof(str))) {
        addr = str;
      }
      break;
  }
  if (addr.empty())
    addr = base::StringPrintf("<Unknown address family: %d>", sa->sa_family);
  return addr;
}

int ConnectSocket(const std::string& host, uint16_t port) {
  std::string service = std::to_string(port);
  addrinfo hints = {0, AF_INET, SOCK_STREAM};
  addrinfo* result = nullptr;
  if (getaddrinfo(host.c_str(), service.c_str(), &hints, &result)) {
    PLOG(WARNING) << "Failed to resolve host name: " << host;
    return -1;
  }

  int socket_fd = -1;
  for (const addrinfo* info = result; info != nullptr; info = info->ai_next) {
    socket_fd = socket(info->ai_family, info->ai_socktype, info->ai_protocol);
    if (socket_fd < 0)
      continue;

    std::string addr = GetIPAddress(info->ai_addr);
    LOG(INFO) << "Connecting to address: " << addr;
    if (connect(socket_fd, info->ai_addr, info->ai_addrlen) == 0)
      break;  // Success.

    PLOG(WARNING) << "Failed to connect to address: " << addr;
    close(socket_fd);
    socket_fd = -1;
  }

  freeaddrinfo(result);
  return socket_fd;
}

void OnSuccess(const Network::OpenSslSocketCallback& callback,
               brillo::StreamPtr tls_stream) {
  callback.Run(
      std::unique_ptr<weave::Stream>{new SocketStream{std::move(tls_stream)}},
      nullptr);
}

void OnError(const weave::DoneCallback& callback,
             const brillo::Error* brillo_error) {
  weave::ErrorPtr error;
  ConvertError(*brillo_error, &error);
  callback.Run(std::move(error));
}

}  // namespace

void SocketStream::Read(void* buffer,
                        size_t size_to_read,
                        const ReadCallback& callback) {
  brillo::ErrorPtr brillo_error;
  if (!ptr_->ReadAsync(
          buffer, size_to_read,
          base::Bind([](const ReadCallback& callback,
                        size_t size) { callback.Run(size, nullptr); },
                     callback),
          base::Bind(&OnError, base::Bind(callback, 0)), &brillo_error)) {
    weave::ErrorPtr error;
    ConvertError(*brillo_error, &error);
    base::MessageLoop::current()->task_runner()->PostTask(
        FROM_HERE, base::Bind(callback, 0, base::Passed(&error)));
  }
}

void SocketStream::Write(const void* buffer,
                         size_t size_to_write,
                         const WriteCallback& callback) {
  brillo::ErrorPtr brillo_error;
  if (!ptr_->WriteAllAsync(buffer, size_to_write, base::Bind(callback, nullptr),
                           base::Bind(&OnError, callback), &brillo_error)) {
    weave::ErrorPtr error;
    ConvertError(*brillo_error, &error);
    base::MessageLoop::current()->task_runner()->PostTask(
        FROM_HERE, base::Bind(callback, base::Passed(&error)));
  }
}

void SocketStream::CancelPendingOperations() {
  ptr_->CancelPendingAsyncOperations();
}

std::unique_ptr<weave::Stream> SocketStream::ConnectBlocking(
    const std::string& host, uint16_t port) {
  int socket_fd = ConnectSocket(host, port);
  if (socket_fd <= 0)
    return nullptr;

  auto ptr_ = brillo::FileStream::FromFileDescriptor(socket_fd, true, nullptr);
  if (ptr_)
    return std::unique_ptr<Stream>{new SocketStream{std::move(ptr_)}};

  close(socket_fd);
  return nullptr;
}

void SocketStream::TlsConnect(std::unique_ptr<Stream> socket,
                              const std::string& host,
                              const Network::OpenSslSocketCallback& callback) {
  SocketStream* stream = static_cast<SocketStream*>(socket.get());
  brillo::TlsStream::Connect(
      std::move(stream->ptr_), host, base::Bind(&OnSuccess, callback),
      base::Bind(&OnError, base::Bind(callback, nullptr)));
}

}  // namespace buffet
