/**
 * @file service_types.h
 *
 * @brief Service (types).
 *
 * Copyright 2007-2008, Freie Universitaet Berlin. All rights reserved.
 * Please refer to the COPYING file for detailed licensing information.
 *
 * @author Georg Wittenburg
 *
 * $Id: service_types.h 2685 2008-06-25 16:38:56Z wittenbu $
 */

#ifndef SERVICE_TYPES_H
#define SERVICE_TYPES_H

#include "../types.h"
#include "../placement/placement_types.h"



/**
 * @brief Type of the service ID.
 */
typedef char	SERVICE_id_t;

/**
 * @brief Length of the service ID string.
 */
#define SERVICE_ID_LENGTH	8



#define SERVICE_STATE_INIT		0x0	///< Service is initializing.
#define SERVICE_STATE_RUNNING		0x1	///< Service is running.
#define SERVICE_STATE_REPLICATING	0x2	///< Service is replicating to another node.
#define SERVICE_STATE_REDIRECTING	0x3	///< Service is redirecting requests to another node.
#define SERVICE_STATE_STOPPED		0x4	///< Service is stopped.

struct SERVICE_outgoing_replication;
struct SERVICE_incoming_replication;

/**
 * @brief Service data structure.
 */
typedef struct {
	SERVICE_id_t				id[SERVICE_ID_LENGTH];		///< Service ID.
	uint8_t					state;				///< Current state.
	char*					data;				///< Pointer to service data.
	size_t					data_size;			///< Size of service data in bytes.
	struct SERVICE_outgoing_replication*	outgoing_replication;		///< Pointer to outgoing replication.
	struct SERVICE_incoming_replication*	incoming_replication;		///< Pointer to incoming replication.
	C_addr_t				redirect_addr;			///< Address of node to redirect requests to.
	PLACEMENT_data_t*			placement_data;			///< Data and statistics for service placement.
} SERVICE_service_t;

/**
 * @brief Entry in the service cache.
 */
typedef struct {
	SERVICE_id_t				service_id[SERVICE_ID_LENGTH];	///< Service ID.
	C_addr_t				server;				///< Address of the server.
	uint16_t				age;				///< Age of this entry.
	bool					reachable;			///< Flag whether this entry is reachable.
	uint16_t				callback_id;			///< ID of the callback for delayed removal.
} SERVICE_service_cache_entry_t;

/**
 * @brief Data request data structure.
 */
typedef struct {
	SERVICE_id_t				service_id[SERVICE_ID_LENGTH];	///< Service ID.
	uint16_t				offset;				///< Offset in service data.
	size_t					size;				///< Request size in bytes.
} SERVICE_data_request_t;

/**
 * @brief Data update data structure.
 */
typedef struct {
	SERVICE_id_t				service_id[SERVICE_ID_LENGTH];	///< Service ID.
	uint16_t				offset;				///< Offset in service data.
	size_t					size;				///< Update size in bytes.
	const char*				data;				///< New service data.
} SERVICE_data_update_t;

/**
 * @brief Stream request data structure.
 */
typedef struct {
	SERVICE_id_t				service_id[SERVICE_ID_LENGTH];	///< Service ID.
	uint16_t				offset;				///< Offset in service data.
	size_t					size;				///< Request size in bytes.
	C_time_t				interval;			///< Request interval in seconds.
	C_time_t				duration;			///< Request duration in seconds.
} SERVICE_stream_request_t;

/**
 * @brief Active stream being served.
 */
typedef struct {
	C_addr_t				to;				///< Address of the destination node.
	SERVICE_id_t				service_id[SERVICE_ID_LENGTH];	///< Service ID.
	uint16_t				offset;				///< Offset in service data.
	size_t					size;				///< Request size in bytes.
	C_time_t				interval;			///< Request interval in seconds.
	C_time_t				end_time;			///< Request duration in seconds.
} SERVICE_stream_t;

/**
 * @brief Segment of service data.
 */
typedef struct {
	uint16_t				offset;				///< Segment offset.
	size_t					size;				///< Segment size.
} SERVICE_segment_t;

/**
 * @brief Service replication result.
 */
typedef struct {
	C_errno_t				error_code;			///< Error code.
	callback_parameter_t			parameter;			///< Parameter for callback function.
} SERVICE_replication_result_t;

/**
 * @brief Outgoing service replication.
 */
typedef struct SERVICE_outgoing_replication {
	SERVICE_service_t*			service;			///< Pointer to service.
	C_addr_t				destination;			///< Address of destination node.
	uint16_t				callback_id;			///< ID of the timeout callback.
	callback_function_t			callback;			///< Callback function.
	SERVICE_replication_result_t*		result;				///< Pointer to replication result.
} SERVICE_outgoing_replication_t;

/**
 * @brief Incoming service replication.
 */
typedef struct SERVICE_incoming_replication {
	SERVICE_service_t*			service;			///< Pointer to service.
	C_addr_t				source;				///< Address of source node.
	list_t*					missing_segments;		///< List of missing service data segments.
	uint16_t				callback_id;			///< ID of the timeout callback.
} SERVICE_incoming_replication_t;

/**
 * @brief Service migration result.
 */
typedef struct {
	SERVICE_id_t				service_id[SERVICE_ID_LENGTH];	///< Service ID.
	C_errno_t				error_code;			///< Error code.
	callback_parameter_t			parameter;			///< Parameter for callback function.
} SERVICE_migration_result_t;

/**
 * @brief Service migration.
 */
typedef struct {
	SERVICE_service_t*			service;			///< Pointer to service.
	C_addr_t				destination;			///< Address of destination node.
	callback_function_t			callback;			///< Callback function.
	SERVICE_migration_result_t*		result;				///< Pointer to migration result.
} SERVICE_migration_t;



/*
 * Packet types.
 */

/**
 * @brief SERVICE DATA REQUEST packet.
 */
typedef struct {
	SERVICE_id_t				service_id[SERVICE_ID_LENGTH];	///< Service ID.
	uint16_t				offset;				///< Offset in service data.
	size_t					size;				///< Request size in bytes.
	C_time_t				start_time;			///< Start time of request.
} SERVICE_CLIENT_DATA_REQUEST_packet_t;

/**
 * @brief SERVICE DATA UPDATE packet header.
 */
typedef struct {
	SERVICE_id_t				service_id[SERVICE_ID_LENGTH];	///< Service ID.
	uint16_t				offset;				///< Offset in service data.
} SERVICE_CLIENT_DATA_UPDATE_packet_t;

/**
 * @brief SERVICE STREAM REQUEST packet.
 */
typedef SERVICE_stream_request_t SERVICE_CLIENT_STREAM_REQUEST_packet_t;

/**
 * @brief SERVICE DATA ITEM packet.
 */
typedef struct {
	SERVICE_id_t				service_id[SERVICE_ID_LENGTH];	///< Service ID.
	C_time_t				start_time;			///< Start time of request.
	C_addr_t				redirect_addr;			///< Address of new server, if service is redirecting.
} SERVICE_SERVER_DATA_ITEM_packet_t;

/**
 * @brief SERVICE STREAM ITEM packet.
 */
typedef struct {
	SERVICE_id_t				service_id[SERVICE_ID_LENGTH];	///< Service ID.
	C_addr_t				redirect_addr;			///< Address of new server, if service is redirecting.
} SERVICE_SERVER_STREAM_ITEM_packet_t;

/**
 * @brief SERVICE SERVER NOT AVAILABLE packet.
 */
typedef struct {
	SERVICE_id_t				service_id[SERVICE_ID_LENGTH];	///< Service ID.
	C_addr_t				redirect_addr;			///< Address of new server, if service is redirecting.
} SERVICE_SERVER_NOT_AVAILABLE_packet_t;

/**
 * @brief SERVICE REPLICATION REQUEST packet.
 */
typedef struct {
	SERVICE_id_t				service_id[SERVICE_ID_LENGTH];	///< Service ID.
	size_t					service_data_size;		///< Size of service data in bytes.
} SERVICE_REPLICATION_REQUEST_packet_t;

/**
 * @brief SERVICE REPLICATION DATA packet.
 */
typedef struct {
	SERVICE_id_t				service_id[SERVICE_ID_LENGTH];	///< Service ID.
	uint16_t				segment_offset;			///< Offset of service data segment.
} SERVICE_REPLICATION_DATA_packet_t;

/**
 * @brief SERVICE REPLICATION ACK packet.
 */
typedef struct {
	SERVICE_id_t				service_id[SERVICE_ID_LENGTH];	///< Service ID.
	SERVICE_segment_t			next_segment;			///< Next segment to transmit.
} SERVICE_REPLICATION_ACK_packet_t;

/**
 * @brief SERVICE REPLICATION NACK packet.
 */
typedef struct {
	SERVICE_id_t				service_id[SERVICE_ID_LENGTH];	///< Service ID.
	C_errno_t				error_code;			///< Error code.
} SERVICE_REPLICATION_NACK_packet_t;

#endif	// SERVICE_TYPES_H
