//
// 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 <sys/time.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#include <stdio.h> // TODO REMOVE

#include "socket.h"

////////////////////////////////////////////////////////////////////////////////
// Private

// Num seconds since Jan 1 1970 (UTC)
#ifdef _WIN32
// SOL
#else
  double __gettime() {
    struct timeval v;
    gettimeofday(&v, (struct timezone*) NULL);
    return v.tv_sec + v.tv_usec/1.0e6;
  }
#endif

#define WAIT_MODE_R  1
#define WAIT_MODE_W  2
#define WAIT_MODE_C  (WAIT_MODE_R|WAIT_MODE_W)
T_ERRCODE socket_wait(p_socket sock, int mode, int timeout) {
  int ret = 0;
  fd_set rfds, wfds;
  struct timeval tv;
  double end, t;
  if (!timeout) {
    return TIMEOUT;
  }

  end = __gettime() + timeout/1000;
  do {
    FD_ZERO(&rfds);
    FD_ZERO(&wfds);

    // Specify what I/O operations we care about
    if (mode & WAIT_MODE_R) {
      FD_SET(*sock, &rfds);
    }
    if (mode & WAIT_MODE_W) {
      FD_SET(*sock, &wfds);
    }

    // Check for timeout
    t = end - __gettime();
    if (t < 0.0) {
      break;
    }

    // Wait
    tv.tv_sec = (int)t;
    tv.tv_usec = (int)((t - tv.tv_sec) * 1.0e6);
    ret = select(*sock+1, &rfds, &wfds, NULL, &tv);
  } while (ret == -1 && errno == EINTR);
  if (ret == -1) {
    return errno;
  }

  // Check for timeout
  if (ret == 0) {
    return TIMEOUT;
  }

  return SUCCESS;
}

////////////////////////////////////////////////////////////////////////////////
// General

T_ERRCODE socket_create(p_socket sock, int domain, int type, int protocol) {
  *sock = socket(domain, type, protocol);
  if (*sock > 0) {
    return SUCCESS;
  } else {
    return errno;
  }
}

T_ERRCODE socket_destroy(p_socket sock) {
  // TODO Figure out if I should be free-ing this
  if (*sock > 0) {
    (void)socket_setblocking(sock);
    close(*sock);
    *sock = -1;
  }
  return SUCCESS;
}

T_ERRCODE socket_bind(p_socket sock, p_sa addr, int addr_len) {
  int ret = socket_setblocking(sock);
  if (ret != SUCCESS) {
    return ret;
  }
  if (bind(*sock, addr, addr_len)) {
    ret = errno;
  }
  int ret2 = socket_setnonblocking(sock);
  return ret == SUCCESS ? ret2 : ret;
}

T_ERRCODE socket_get_info(p_socket sock, short *port, char *buf, size_t len) {
  struct sockaddr_storage sa;
  memset(&sa, 0, sizeof(sa));
  socklen_t addrlen = sizeof(sa);
  int rc = getsockname(*sock, (struct sockaddr*)&sa, &addrlen);
  if (!rc) {
    if (sa.ss_family == AF_INET6) {
      struct sockaddr_in6* sin = (struct sockaddr_in6*)(&sa);
      if (!inet_ntop(AF_INET6, &sin->sin6_addr, buf, len)) {
        return errno;
      }
      *port = ntohs(sin->sin6_port);
    } else {
      struct sockaddr_in* sin = (struct sockaddr_in*)(&sa);
      if (!inet_ntop(AF_INET, &sin->sin_addr, buf, len)) {
        return errno;
      }
      *port = ntohs(sin->sin_port);
    }
    return SUCCESS;
  }
  return errno;
}

////////////////////////////////////////////////////////////////////////////////
// Server

T_ERRCODE socket_accept(p_socket sock, p_socket client,
                  p_sa addr, socklen_t *addrlen, int timeout) {
  int err;
  if (*sock < 0) {
    return CLOSED;
  }
  do {
    *client = accept(*sock, addr, addrlen);
    if (*client > 0) {
      return SUCCESS;
    }
  } while ((err = errno) == EINTR);

  if (err == EAGAIN || err == ECONNABORTED) {
    return socket_wait(sock, WAIT_MODE_R, timeout);
  }

  return err;
}

T_ERRCODE socket_listen(p_socket sock, int backlog) {
  int ret = socket_setblocking(sock);
  if (ret != SUCCESS) {
    return ret;
  }
  if (listen(*sock, backlog)) {
    ret = errno;
  }
  int ret2 = socket_setnonblocking(sock);
  return ret == SUCCESS ? ret2 : ret;
}

////////////////////////////////////////////////////////////////////////////////
// Client

T_ERRCODE socket_connect(p_socket sock, p_sa addr, int addr_len, int timeout) {
  int err;
  if (*sock < 0) {
    return CLOSED;
  }

  do {
    if (connect(*sock, addr, addr_len) == 0) {
      return SUCCESS;
    }
  } while ((err = errno) == EINTR);
  if (err != EINPROGRESS && err != EAGAIN) {
    return err;
  }
  return socket_wait(sock, WAIT_MODE_C, timeout);
}

T_ERRCODE socket_send(
  p_socket sock, const char *data, size_t len, int timeout) {
  int err, put = 0;
  if (*sock < 0) {
    return CLOSED;
  }
  do {
    put = send(*sock, data, len, 0);
    if (put > 0) {
      return SUCCESS;
    }
  } while ((err = errno) == EINTR);

  if (err == EAGAIN) {
    return socket_wait(sock, WAIT_MODE_W, timeout);
  }

  return err;
}

T_ERRCODE socket_recv(
  p_socket sock, char *data, size_t len, int timeout, int *received) {
  int err, got = 0;
  if (*sock < 0) {
    return CLOSED;
  }
  *received = 0;

  do {
    got = recv(*sock, data, len, 0);
    if (got > 0) {
      *received = got;
      return SUCCESS;
    }
    err = errno;

    // Connection has been closed by peer
    if (got == 0) {
      return CLOSED;
    }
  } while (err == EINTR);

  if (err == EAGAIN) {
    return socket_wait(sock, WAIT_MODE_R, timeout);
  }

  return err;
}

////////////////////////////////////////////////////////////////////////////////
// Util

T_ERRCODE socket_setnonblocking(p_socket sock) {
  int flags = fcntl(*sock, F_GETFL, 0);
  flags |= O_NONBLOCK;
  return fcntl(*sock, F_SETFL, flags) != -1 ? SUCCESS : errno;
}

T_ERRCODE socket_setblocking(p_socket sock) {
  int flags = fcntl(*sock, F_GETFL, 0);
  flags &= (~(O_NONBLOCK));
  return fcntl(*sock, F_SETFL, flags) != -1 ? SUCCESS : errno;
}

////////////////////////////////////////////////////////////////////////////////
// TCP

#define ERRORSTR_RETURN(err) \
  if (err == SUCCESS) { \
    return NULL; \
  } else if (err == TIMEOUT) { \
    return TIMEOUT_MSG; \
  } else if (err == CLOSED) { \
    return CLOSED_MSG; \
  } \
  return strerror(err)

const char * tcp_create(p_socket sock) {
  // TODO support IPv6
  int err = socket_create(sock, AF_INET, SOCK_STREAM, 0);
  ERRORSTR_RETURN(err);
}

const char * tcp_destroy(p_socket sock) {
  int err = socket_destroy(sock);
  ERRORSTR_RETURN(err);
}

const char * tcp_bind(p_socket sock, const char *host, unsigned short port) {
  // TODO support IPv6
  int err;
  struct hostent *h;
  struct sockaddr_in local;
  memset(&local, 0, sizeof(local));
  local.sin_family = AF_INET;
  local.sin_addr.s_addr = htonl(INADDR_ANY);
  local.sin_port = htons(port);
  if (strcmp(host, "*") && !inet_aton(host, &local.sin_addr)) {
    h = gethostbyname(host);
    if (!h) {
      return hstrerror(h_errno);
    }
    memcpy(&local.sin_addr,
           (struct in_addr *)h->h_addr_list[0],
           sizeof(struct in_addr));
  }
  err = socket_bind(sock, (p_sa) &local, sizeof(local));
  ERRORSTR_RETURN(err);
}

const char * tcp_listen(p_socket sock, int backlog) {
  int err = socket_listen(sock, backlog);
  ERRORSTR_RETURN(err);
}

const char * tcp_accept(p_socket sock, p_socket client, int timeout) {
  int err = socket_accept(sock, client, NULL, NULL, timeout);
  ERRORSTR_RETURN(err);
}

const char * tcp_connect(p_socket sock,
                         const char *host,
                         unsigned short port,
                         int timeout) {
  // TODO support IPv6
  int err;
  struct hostent *h;
  struct sockaddr_in remote;
  memset(&remote, 0, sizeof(remote));
  remote.sin_family = AF_INET;
  remote.sin_port = htons(port);
  if (strcmp(host, "*") && !inet_aton(host, &remote.sin_addr)) {
    h = gethostbyname(host);
    if (!h) {
      return hstrerror(h_errno);
    }
    memcpy(&remote.sin_addr,
           (struct in_addr *)h->h_addr_list[0],
           sizeof(struct in_addr));
  }
  err = socket_connect(sock, (p_sa) &remote, sizeof(remote), timeout);
  ERRORSTR_RETURN(err);
}

const char * tcp_create_and_connect(p_socket sock,
                                    const char *host,
                                    unsigned short port,
                                    int timeout) {
  int err;
  struct sockaddr_in sa4;
  struct sockaddr_in6 sa6;

  memset(&sa4, 0, sizeof(sa4));
  sa4.sin_family = AF_INET;
  sa4.sin_port = htons(port);
  memset(&sa6, 0, sizeof(sa6));
  sa6.sin6_family = AF_INET6;
  sa6.sin6_port = htons(port);

  if (inet_pton(AF_INET, host, &sa4.sin_addr)) {
    socket_create(sock, AF_INET, SOCK_STREAM, 0);
    err = socket_connect(sock, (p_sa) &sa4, sizeof(sa4), timeout);
    ERRORSTR_RETURN(err);
  } else if (inet_pton(AF_INET6, host, &sa6.sin6_addr)) {
    socket_create(sock, AF_INET6, SOCK_STREAM, 0);
    err = socket_connect(sock, (p_sa) &sa6, sizeof(sa6), timeout);
    ERRORSTR_RETURN(err);
  } else {
    struct addrinfo hints, *servinfo, *rp;
    char portStr[6];
    int rv;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    sprintf(portStr, "%u", port);

    if ((rv = getaddrinfo(host, portStr, &hints, &servinfo)) != 0) {
      return gai_strerror(rv);
    }

    err = TIMEOUT;
    for (rp = servinfo; rp != NULL; rp = rp->ai_next) {
      err = socket_create(sock, rp->ai_family, rp->ai_socktype, rp->ai_protocol);
      if (err != SUCCESS) {
        continue;
      }
      err = socket_connect(sock, (p_sa) rp->ai_addr, rp->ai_addrlen, timeout);
      if (err == SUCCESS) {
        break;
      }
      close(*sock);
    }
    freeaddrinfo(servinfo);
    if (rp == NULL) {
      *sock = -1;
      return "Failed to connect";
    } else {
      ERRORSTR_RETURN(err);
    }
  }
}

#define WRITE_STEP 8192
const char * tcp_send(
  p_socket sock, const char * data, size_t w_len, int timeout) {
  int err;
  size_t put = 0, step;
  if (!w_len) {
    return NULL;
  }

  do {
    step = (WRITE_STEP < w_len - put ? WRITE_STEP : w_len - put);
    err = socket_send(sock, data + put, step, timeout);
    put += step;
  } while (err == SUCCESS && put < w_len);
  ERRORSTR_RETURN(err);
}

const char * tcp_raw_receive(
  p_socket sock, char * data, size_t r_len, int timeout, int *received) {
  int err = socket_recv(sock, data, r_len, timeout, received);
  ERRORSTR_RETURN(err);
}
