// 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/callback_helpers.h>
#include <base/files/file_util.h>
#include <base/strings/stringprintf.h>
#include <base/threading/thread_task_runner_handle.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::ThreadTaskRunnerHandle::Get()->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::ThreadTaskRunnerHandle::Get()->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
