#include <iostream>

#include "Multiplayer.hpp"

#include "engine/api_private.hpp"

using namespace blit;

Multiplayer::Multiplayer(Mode mode, const std::string &address) : mode(mode), address(address) {
    // shouldn't fail unless we ran out of memory
    sock_set = SDLNet_AllocSocketSet(2);
}

Multiplayer::~Multiplayer() {
    if(sock_set)
        SDLNet_FreeSocketSet(sock_set);

    if(socket)
        SDLNet_TCP_Close(socket);

    if(listen_socket)
        SDLNet_TCP_Close(listen_socket);
}

void Multiplayer::update() {
    if(!enabled)
        return;

    if(!socket && !listen_socket) {
        // attempt to reconnect
        auto now = SDL_GetTicks();
        if((now - last_connect_time) > retry_interval) {
            setup();

            last_connect_time = now;
        }
        return;
    }

    int num_ready;

    while((num_ready = SDLNet_CheckSockets(sock_set, 0))) {
      if(num_ready == -1) {
          std::cerr << "Failed to check socket: " << SDLNet_GetError() << std::endl;
          return;
      }

      if(listen_socket && SDLNet_SocketReady(listen_socket)) {
          // new connection
          socket = SDLNet_TCP_Accept(listen_socket);
          if(socket) {
              auto remote_addr = SDLNet_TCP_GetPeerAddress(socket);
              auto ip = SDL_SwapBE32(remote_addr->host);
              std::cout << (ip >> 24) << "." << ((ip >> 16) & 0xFF) << "." << ((ip >> 8) & 0xFF) << "." << (ip & 0xFF) << " connected" << std::endl;

              SDLNet_TCP_AddSocket(sock_set, socket);

              SDLNet_TCP_Send(socket, "32BLMLTI\1", 9);

              // stop listening now
              stop_listening();
          }
      }

      if(!socket || !SDLNet_SocketReady(socket))
          return;

      if(!recv_buf) {
          // read header and setup

          auto read = SDLNet_TCP_Recv(socket, head_buf + head_off, 8 - head_off);

          if(read <= 0) {
            disconnect();
            return;
          }

          head_off += read;

          if(head_off < 8)
            continue;

          if(memcmp(head_buf, "32BLUSER", 8) == 0) {
            // get the length
            int off = 0;

            do {
              read = SDLNet_TCP_Recv(socket, head_buf + off, 2 - off);

              if(read <= 0) {
                disconnect();
                return;
              }

              off += read;
            } while(off != 2);

            recv_len = head_buf[0] | (head_buf[1] << 8);
            recv_buf = new uint8_t[recv_len];
            recv_off = 0;
            head_off = 0;

          } else if(memcmp(head_buf, "32BLMLTI", 8) == 0) {
            // handle the handshake packet
            SDLNet_TCP_Recv(socket, head_buf, 1);
            handshake = head_buf[0] != 0;

            if(mode == Mode::Connect && head_buf[0] == 1)
              SDLNet_TCP_Send(socket, "32BLMLTI\2", 9);

            head_off = 0;
          } else {
            std::cerr << "Unexpected header: " << std::string(reinterpret_cast<char *>(head_buf), 8) << std::endl;
            head_off = 0;
          }

          if(!recv_buf || SDLNet_CheckSockets(sock_set, 0) <= 0)
              return;
      }

      auto read = SDLNet_TCP_Recv(socket, recv_buf + recv_off, recv_len - recv_off);
      if(read <= 0) {
          // failed/disconnected
          delete[] recv_buf;
          recv_buf = nullptr;
          disconnect();
          return;
      }

      recv_off += read;

      // got message, pass to user
      if(recv_off == recv_len) {
          if(api_data.message_received)
              api_data.message_received(recv_buf, recv_len);

          delete[] recv_buf;
          recv_buf = nullptr;
      }
    }
}

bool Multiplayer::is_connected() const {
    return socket != nullptr && handshake;
}

void Multiplayer::set_enabled(bool enabled) {
    if(enabled) {
        setup();
    } else {
        disconnect();

        if(listen_socket) {
            SDLNet_TCP_DelSocket(sock_set, listen_socket);
            SDLNet_TCP_Close(listen_socket);
        }
    }

    this->enabled = enabled;
}

void Multiplayer::send_message(const uint8_t *data, uint16_t length) {
    if(!socket)
        return;

    uint8_t head[]{
        '3', '2', 'B', 'L',
        'U', 'S', 'E', 'R',
        static_cast<uint8_t>(length),
        static_cast<uint8_t>(length >> 8)
    };

    if(SDLNet_TCP_Send(socket, head, 10) != 10) {
        // failed
        disconnect();
        return;
    }

    auto sent = SDLNet_TCP_Send(socket, data, length);
    if(sent < length) {
        // failed
        disconnect();
    }
}

void Multiplayer::setup() {
    const uint16_t port = 0x32B1;

    IPaddress ip;

    // try connecting first for auto
    if(mode != Mode::Listen) {
        if(SDLNet_ResolveHost(&ip, address.c_str(), port) == -1) {
            std::cerr << "Failed to resolve \"" << address << "\"!" << std::endl;
        } else
            socket = SDLNet_TCP_Open(&ip);
    }

    if(!socket && mode != Mode::Connect) {
        // try hosting instead unless connecting was specified
        if(SDLNet_ResolveHost(&ip, nullptr, port) == -1) {
            // this can't fail
            std::cerr << "Failed to resolve \"any\" address!" << std::endl;
        } else
            listen_socket = SDLNet_TCP_Open(&ip);
    }

    if(!socket && !listen_socket) {
        std::cerr << "Failed to open socket: " << SDLNet_GetError() << std::endl;
        return;
    }

    if(listen_socket) {
        SDLNet_TCP_AddSocket(sock_set, listen_socket);
        mode = Mode::Listen;
    } else {
        SDLNet_TCP_AddSocket(sock_set, socket);
        mode = Mode::Connect;
    }
}

void Multiplayer::disconnect() {
    if(!socket)
        return;

    SDLNet_TCP_DelSocket(sock_set, socket);

    SDLNet_TCP_Close(socket);
    socket = nullptr;

    handshake = false;
}

void Multiplayer::stop_listening() {
    SDLNet_TCP_DelSocket(sock_set, listen_socket);

    SDLNet_TCP_Close(listen_socket);
    listen_socket = nullptr;
}
