#include <cerrno>
#include <stdexcept>
#include "includes/sock.hpp"
#include "includes/exception_consts.hpp"
#include "includes/easysock.hpp"

void Sock::create_socket()  {
	dest = (struct sockaddr *)malloc(sizeof(struct sockaddr));
}

Sock::Sock(int ip_ver, char protocol, const char* address, int port) {
	/* Error checking */
	if (ip_ver != 4 && ip_ver != 6) {
		throw std::invalid_argument("Invalid IP address type");
	}
	if (port < 1024 || port > 65535) {
		throw std::invalid_argument("Invalid port");
	}
	if (protocol != 'T' && protocol != 'U') {
		throw std::invalid_argument("Invalid protocol");
	}

	this->ip_ver = ip_ver;
	this->protocol = protocol;
	this->port = port;
	this->address = std::string(address);

	/* Check to see if the given IP address matches the given ip_ver */
        if ((check_ip_ver(address) != 6 && ip_ver == 6) || (check_ip_ver(address) != 4 && ip_ver == 4)) {
		throw std::invalid_argument("Invalid IP address for given type.");
	}

	try {
		create_socket();
	} catch (int e) {
		throw;
	}
}

void Sock::sendAll(std::string to_send) {
	int str_length = to_send.length();
	int num_bytes_sent = 0; /* Number of bytes sent in one call to send */
	int total_bytes_sent = 0; /* Total number of bytes sent */

	while (total_bytes_sent < str_length) {
		num_bytes_sent = send(this->getSockFD(), to_send.substr(total_bytes_sent).data(), str_length - total_bytes_sent, 0);
		total_bytes_sent += num_bytes_sent;
	}

	return;
}

std::string Sock::recvAll() {
	std::string string = std::string();
	char* buffer = (char *)malloc(100);
	while (recv(this->getSockFD(), buffer, 100, 0) != 0) {
		string.append(std::string(buffer));
	}

	return string;
}

int Sock::getSockFD() {
	return sock_fd;
}