#include <stdlib.h>
#include <string.h>

#include "port_internal.h"
#include "context_internal.h"
#include "debug.h"

struct sepol_port {
	/* Low - High range. Same for single ports. */
	int low, high;

	/* Protocol */
	int proto;

	/* Context */
	sepol_context_t *con;
};

struct sepol_port_key {
	/* Low - High range. Same for single ports. */
	int low, high;

	/* Protocol */
	int proto;
};

/* Key */
int sepol_port_key_create(sepol_handle_t * handle,
			  int low, int high, int proto,
			  sepol_port_key_t ** key_ptr)
{

	sepol_port_key_t *tmp_key =
	    (sepol_port_key_t *) malloc(sizeof(sepol_port_key_t));

	if (!tmp_key) {
		ERR(handle, "out of memory, could not create " "port key");
		return STATUS_ERR;
	}

	tmp_key->low = low;
	tmp_key->high = high;
	tmp_key->proto = proto;

	*key_ptr = tmp_key;
	return STATUS_SUCCESS;
}

hidden_def(sepol_port_key_create)

void sepol_port_key_unpack(const sepol_port_key_t * key,
			   int *low, int *high, int *proto)
{

	*low = key->low;
	*high = key->high;
	*proto = key->proto;
}

hidden_def(sepol_port_key_unpack)

int sepol_port_key_extract(sepol_handle_t * handle,
			   const sepol_port_t * port,
			   sepol_port_key_t ** key_ptr)
{

	if (sepol_port_key_create
	    (handle, port->low, port->high, port->proto, key_ptr) < 0) {

		ERR(handle, "could not extract key from port %s %d:%d",
		    sepol_port_get_proto_str(port->proto),
		    port->low, port->high);

		return STATUS_ERR;
	}

	return STATUS_SUCCESS;
}

void sepol_port_key_free(sepol_port_key_t * key)
{
	free(key);
}

int sepol_port_compare(const sepol_port_t * port, const sepol_port_key_t * key)
{

	if ((port->low == key->low) &&
	    (port->high == key->high) && (port->proto == key->proto))
		return 0;

	if (port->low < key->low)
		return -1;

	else if (key->low < port->low)
		return 1;

	else if (port->high < key->high)
		return -1;

	else if (key->high < port->high)
		return 1;

	else if (port->proto < key->proto)
		return -1;

	else
		return 1;
}

int sepol_port_compare2(const sepol_port_t * port, const sepol_port_t * port2)
{

	if ((port->low == port2->low) &&
	    (port->high == port2->high) && (port->proto == port2->proto))
		return 0;

	if (port->low < port2->low)
		return -1;

	else if (port2->low < port->low)
		return 1;

	else if (port->high < port2->high)
		return -1;

	else if (port2->high < port->high)
		return 1;

	else if (port->proto < port2->proto)
		return -1;

	else
		return 1;
}

/* Port */
int sepol_port_get_low(const sepol_port_t * port)
{

	return port->low;
}

hidden_def(sepol_port_get_low)

int sepol_port_get_high(const sepol_port_t * port)
{

	return port->high;
}

hidden_def(sepol_port_get_high)

void sepol_port_set_port(sepol_port_t * port, int port_num)
{

	port->low = port_num;
	port->high = port_num;
}

void sepol_port_set_range(sepol_port_t * port, int low, int high)
{

	port->low = low;
	port->high = high;
}

hidden_def(sepol_port_set_range)

/* Protocol */
int sepol_port_get_proto(const sepol_port_t * port)
{

	return port->proto;
}

hidden_def(sepol_port_get_proto)

const char *sepol_port_get_proto_str(int proto)
{

	switch (proto) {
	case SEPOL_PROTO_UDP:
		return "udp";
	case SEPOL_PROTO_TCP:
		return "tcp";
	default:
		return "???";
	}
}

hidden_def(sepol_port_get_proto_str)

void sepol_port_set_proto(sepol_port_t * port, int proto)
{

	port->proto = proto;
}

hidden_def(sepol_port_set_proto)

/* Create */
int sepol_port_create(sepol_handle_t * handle, sepol_port_t ** port)
{

	sepol_port_t *tmp_port = (sepol_port_t *) malloc(sizeof(sepol_port_t));

	if (!tmp_port) {
		ERR(handle, "out of memory, could not create " "port record");
		return STATUS_ERR;
	}

	tmp_port->low = 0;
	tmp_port->high = 0;
	tmp_port->proto = SEPOL_PROTO_UDP;
	tmp_port->con = NULL;
	*port = tmp_port;

	return STATUS_SUCCESS;
}

hidden_def(sepol_port_create)

/* Deep copy clone */
int sepol_port_clone(sepol_handle_t * handle,
		     const sepol_port_t * port, sepol_port_t ** port_ptr)
{

	sepol_port_t *new_port = NULL;
	if (sepol_port_create(handle, &new_port) < 0)
		goto err;

	new_port->low = port->low;
	new_port->high = port->high;
	new_port->proto = port->proto;

	if (port->con &&
	    (sepol_context_clone(handle, port->con, &new_port->con) < 0))
		goto err;

	*port_ptr = new_port;
	return STATUS_SUCCESS;

      err:
	ERR(handle, "could not clone port record");
	sepol_port_free(new_port);
	return STATUS_ERR;
}

/* Destroy */
void sepol_port_free(sepol_port_t * port)
{

	if (!port)
		return;

	sepol_context_free(port->con);
	free(port);
}

hidden_def(sepol_port_free)

/* Context */
sepol_context_t *sepol_port_get_con(const sepol_port_t * port)
{

	return port->con;
}

hidden_def(sepol_port_get_con)

int sepol_port_set_con(sepol_handle_t * handle,
		       sepol_port_t * port, sepol_context_t * con)
{

	sepol_context_t *newcon;

	if (sepol_context_clone(handle, con, &newcon) < 0) {
		ERR(handle, "out of memory, could not set port context");
		return STATUS_ERR;
	}

	sepol_context_free(port->con);
	port->con = newcon;
	return STATUS_SUCCESS;
}

hidden_def(sepol_port_set_con)
