// Copyright (c) 2012 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 "tools/android/common/adb_connection.h"

#include <arpa/inet.h>
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "base/stl_util.h"
#include "tools/android/common/net.h"

namespace tools {
namespace {

void CloseSocket(int fd) {
  if (fd >= 0) {
    int old_errno = errno;
    close(fd);
    errno = old_errno;
  }
}

}  // namespace

int ConnectAdbHostSocket(const char* forward_to) {
  // ADB port forward request format: HHHHtcp:port:address.
  // HHHH is the hexidecimal length of the "tcp:port:address" part.
  const size_t kBufferMaxLength = 30;
  const size_t kLengthOfLength = 4;

  const char kAddressPrefix[] = { 't', 'c', 'p', ':' };
  size_t address_length = base::size(kAddressPrefix) + strlen(forward_to);
  if (address_length > kBufferMaxLength - kLengthOfLength) {
    LOG(ERROR) << "Forward to address is too long: " << forward_to;
    return -1;
  }

  char request[kBufferMaxLength];
  memcpy(request + kLengthOfLength, kAddressPrefix, base::size(kAddressPrefix));
  memcpy(request + kLengthOfLength + base::size(kAddressPrefix), forward_to,
         strlen(forward_to));

  char length_buffer[kLengthOfLength + 1];
  snprintf(length_buffer, base::size(length_buffer), "%04X",
           static_cast<int>(address_length));
  memcpy(request, length_buffer, kLengthOfLength);

  int host_socket = socket(AF_INET, SOCK_STREAM, 0);
  if (host_socket < 0) {
    LOG(ERROR) << "Failed to create adb socket: " << strerror(errno);
    return -1;
  }

  DisableNagle(host_socket);

  const int kAdbPort = 5037;
  sockaddr_in addr;
  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  addr.sin_port = htons(kAdbPort);
  if (HANDLE_EINTR(connect(host_socket, reinterpret_cast<sockaddr*>(&addr),
                           sizeof(addr))) < 0) {
    LOG(ERROR) << "Failed to connect adb socket: " << strerror(errno);
    CloseSocket(host_socket);
    return -1;
  }

  size_t bytes_remaining = address_length + kLengthOfLength;
  size_t bytes_sent = 0;
  while (bytes_remaining > 0) {
    int ret = HANDLE_EINTR(send(host_socket, request + bytes_sent,
                                bytes_remaining, 0));
    if (ret < 0) {
      LOG(ERROR) << "Failed to send request: " << strerror(errno);
      CloseSocket(host_socket);
      return -1;
    }

    bytes_sent += ret;
    bytes_remaining -= ret;
  }

  const int kAdbStatusLength = 4;
  char response[kBufferMaxLength];
  int response_length = HANDLE_EINTR(recv(host_socket, response,
                                          kBufferMaxLength, 0));
  if (response_length < kAdbStatusLength ||
      strncmp("OKAY", response, kAdbStatusLength) != 0) {
    LOG(ERROR) << "Bad response from ADB: length: " << response_length
               << " data: " << DumpBinary(response, response_length);
    CloseSocket(host_socket);
    return -1;
  }

  return host_socket;
}

}  // namespace tools
