/* 
 * File:   error.h
 * Author: Arthur Brandao
 *
 * Created on 8 novembre 2018
 */

#ifndef ERROR_H
#define ERROR_H

#include <stdio.h>
#include <time.h>

/* --- Macro --- */
#define serror(str) fprintf(stderr, str" : %s\n", serrlib[serrno])
#define strserror(index) serrlib[index]
#define adderror(str) fprintf(stderr, "Erreur dans le fichier "__FILE__" ligne %d, %s\n", __LINE__, str)
#define addperror(str) fprintf(stderr, "Erreur dans le fichier "__FILE__" ligne %d, ", __LINE__); perror(str" ")
#define addserror(str) fprintf(stderr, "Erreur dans le fichier "__FILE__" ligne %d, %s : %s\n", __LINE__, str, strserror(serrno))

/* --- Constantes Generales --- */
#define ERR -1
#define FAIL 0
#define SUCCESS 1

/* --- Constantes Erreurs --- */
#define SENONE 0
#define SESOCKET 1
#define SEBIND 2
#define SEACCEPT 3
#define SERECEIVE 4
#define SESEND 5
#define SECLOSE 6
#define SETYPE 7

/* --- Structure --- */
typedef struct{
    int init; //Initialisée ou non
    char* filename; //Nom du fichier
    int errfd; //Descripteur de fichier de la sortie standard des erreurs
    time_t start; //TImestamp de debut
    /* Fonctions */
    void (*end)(); //Termine le gestionnaire d'erreur
    void (*exit)(); //Termine le programme avec EXIT_SUCCESS
    void (*exit_err)(); //Termine le programme avec EXIT_FAILURE
    void (*exit_status)(int); //Termine le programme avec un status utilisateur
    void (*exit_msg)(int, const char*, ...); //Termine le programme avec un status utilisateur et un message dans la sortie standard
    void (*add)(const char*, ...); //Ajoute un message dans le log
    void (*print)(const char*, ...); //Affiche un message dans la sortie d'erreur
    void (*printadd)(const char*, ...); //Fonction print + add
}Error;

/* --- Extern --- */
extern int serrno; //Server Errno
extern char* serrlib[];
extern Error error;

/* --- Fonctions --- */
/**
 * Change un fd par la valeur d'un autre fd
 * @param int fd accueil
 * @param int fd source fermé par la fonction
 * @return int Le nouveau fd du fichier qui avait le fd d'accueil
 */
int redirect_fd(int, int);

/**
 * Change un fd par la valeur d'un autre fd
 * @param int fd accueil
 * @param int fd source
 * @return int Le nouveau fd du fichier qui avait le fd d'accueil
 */
int redirect_fd2(int, int);

/**
 * Initialise la gestion d'erreur
 * Le log sera nommé err-timestamp.log
 */
void error_init();

/**
 * Initialise le log d'erreur
 * @param char* Le nom du fichier de log
 */
void error_finit(const char*);

#endif /* ERROR_H */

