#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <sys/dir.h>
#include <dirent.h>
#include "vrrpd.h"

#ifdef use_linux_libc5
#endif

typedef u_int32_t u32;
typedef u_int16_t u16;
typedef u_int8_t u8;

#if defined(SIOCGPARAMS)  && SIOCGPARAMS != SIOCDEVPRIVATE+3
#error Changed definition for SIOCGPARAMS
#else
#define SIOCGPARAMS (SIOCDEVPRIVATE+3) 		/* Read operational parameters. */
#define SIOCSPARAMS (SIOCDEVPRIVATE+4) 		/* Set operational parameters. */
#endif
#define DATA_MAX 10000

int max_monitor = 9;
char version1[5] = "2.0";
char buff[80];
char data[DATA_MAX];
char pidend[6] = ".pid";
char separetepath[2] = "/";
int monitor;
int pid;
int ix = 0;
int max_mac = 6;
// Five loop with twice SIGNAL
int max_count = 5;
int nb;
int retval;

static char PidDir[FILENAME_MAX+1];
char namepid[FILENAME_MAX+1] = "vrrpd_";
char temp[FILENAME_MAX+1];
char finalfile[FILENAME_MAX+1];

DIR *currentDir;
struct dirent *fichier;

const char shortopts[] = "aA:bB:fF:Mn:sS:hH:p:rRsvVw?";

struct option longopts[] = {
    /* { name  has_arg  *flag  val } */
    {"state", 0, 0, 's'},
    {"help", 0, 0, 'h'},
    {"backup", 0, 0, 'b'},
    {"reduce", 0, 0, 'r'},
    {"increase", 0, 0, 'i'},
    {"master", 0, 0, 'm'},
    {"version", 0, 0, 'v'},
    {0, 0, 0, 0}
};

char ligne[80];
int cpt = 0;
char buf[80];
int s, i;
FILE *filestate;
FILE *f;

unsigned int opt_a = 0,                    /* Show-all-interfaces flag. */            /* Verbose flag. */
    state = 0,
    version = 0,
    help = 0,
    backup = 0,
    master = 0,
    increase = 0,
    reduce = 0;

void fonctinfo() {
    // Recherche des processus vrrpd dans /proc
    DIR *proc_dir = opendir("/proc");
    if (proc_dir == NULL) {
        perror("opendir(/proc)");
        return;
    }

    struct dirent *entry;
    char pid_file[FILENAME_MAX];
    char cmdline[FILENAME_MAX];
    int count = 0;
    while ((entry = readdir(proc_dir)) != NULL) {
        if (isdigit(entry->d_name[0])) {  // Si le nom du répertoire est un PID
            snprintf(pid_file, sizeof(pid_file) - 1, "/proc/%s/cmdline", entry->d_name); // Limiter la taille du tampon
            FILE *cmdline_file = fopen(pid_file, "r");
            if (cmdline_file != NULL) {
                if (fgets(cmdline, sizeof(cmdline), cmdline_file) != NULL) {
                    // Si le nom du processus contient "vrrpd"
                    if (strstr(cmdline, "vrrpd") != NULL) {
			int pid = atoi(entry->d_name);
                        printf("Processus VRRPD found with PID: %s\n", entry->d_name);
			count++;
			kill(pid,SIGUSR1);
    			sleep(1);
    			char vrrp_tmp[FILENAME_MAX] = VRRP_PIDDIR_DFL;
    			snprintf(temp, sizeof(vrrp_tmp), "/.vrrpstate%d", pid);  
    			strcat(vrrp_tmp, temp);
    			FILE *f = fopen(vrrp_tmp, "r");
			if (f != NULL) {
        			while (fgets(data, DATA_MAX, f) != NULL) {
            				printf("%s", data);  // Affiche les données liées à ce processus
        			}
        			fclose(f);
    			}
            	     }
            	     fclose(cmdline_file);
        	}
	     }
	}
   }
   if (count == 0) {
      printf("No process VRRPD found\n");
   }
   closedir(proc_dir);
}

static void signal_end(int nosig) {
    fprintf(stdout, "\n");
    signal(SIGINT, signal_end);
    return;
}

int main(int argc, char **argv) {
    signal(SIGINT, signal_end);
    int c;
    while ((c = getopt_long(argc, argv, shortopts, longopts, 0)) != EOF)
        switch (c) {
            case 's': state++; break;
            case 'v': version++; break;
            case 'h': help++; break;
            case 'b': backup++; break;
            case 'r': reduce++; break;
            case 'i': increase++; break;
            case 'm': master++; break;
            case '?': help++; break;
	    default: help++; break;
        }

    if (state) {
        fonctinfo();
        return 0;
    }

    if (version) {
        fprintf(stdout, "Atropos %s\n", version1);
        return 0;
    }

    if (argc == 1 || help) {
    	printf("Usage: atropos [options]\n");
    	printf("\nOptions:\n");
    	printf("  --backup\t\tBe backup (caution: Don't use with priority !)\n");
    	printf("  --reduce\t\tReduce priority dynamically priority -10\n");
    	printf("               If vrrpd run with -z : Set the priority after SIGTTIN (not decrement as default)\n");
    	printf("  --increase\t\tIncrease priority dynamically +10\n");
    	printf("               If vrrpd run with -x : Set the priority after SIGTTOU (not increment as default)\n");
    	printf("  --help\t\tThis Page\n");
    	printf("  --state\t\tStatus\n");
    	printf("  --version\t\tVersion\n");
    	printf("\nIt requires to be run as root.\n");
    }

    if (reduce) {
        snprintf(PidDir, sizeof(PidDir), "%s", VRRP_PIDDIR_DFL);
        fprintf(stdout, "Please wait reduce\n");

        sleep(1);
        if (NULL == (currentDir = opendir(PidDir))) {
            perror("opendir()");
        } else {
            while (NULL != (fichier = readdir(currentDir))) {
                if (!strncmp(namepid, fichier->d_name, 6)) {
                    strcpy(finalfile, PidDir);
                    strcat(finalfile, separetepath);
                    strcat(finalfile, fichier->d_name);
                    if ((f = fopen(finalfile, "rb")) != NULL) {
                        fgets(buff, sizeof(buff), f);
                        fclose(f);
                        int pid = atoi(buff);
                        kill(pid, SIGTTIN);
                        finalfile[0] = '\0';
                    }
                }
            }
        }

        fprintf(stdout, "DONE\n");
        return 0;
    }

    if (increase) {
        snprintf(PidDir, sizeof(PidDir), "%s", VRRP_PIDDIR_DFL);
        fprintf(stdout, "Please wait increase\n");

        sleep(1);
        if (NULL == (currentDir = opendir(PidDir))) {
            perror("opendir()");
        } else {
            while (NULL != (fichier = readdir(currentDir))) {
                if (!strncmp(namepid, fichier->d_name, 6)) {
                    strcpy(finalfile, PidDir);
                    strcat(finalfile, separetepath);
                    strcat(finalfile, fichier->d_name);
                    if ((f = fopen(finalfile, "rb")) != NULL) {
                        fgets(buff, sizeof(buff), f);
                        fclose(f);
                        int pid = atoi(buff);
                        kill(pid, SIGTTOU);
                        finalfile[0] = '\0';
                    }
                }
            }
        }
        fprintf(stdout, "DONE\n");
        return 0;
    }

    if (backup) {
        snprintf(PidDir, sizeof(PidDir), "%s", VRRP_PIDDIR_DFL);
        fprintf(stdout, "VRRPD BACKUP\n");
        fprintf(stdout, "PLEASE WAIT\n");
        for (ix = 0; ix <= max_count; ix++) {
            fprintf(stderr, "\n");
            fprintf(stderr, "Stage: %d|%d:  ", ix, max_count);
            sleep(1);
            fprintf(stderr, "\b");
            fprintf(stderr, "|");
            if (NULL == (currentDir = opendir(PidDir))) {
                perror("opendir()");
            } else {
                while (NULL != (fichier = readdir(currentDir))) {
                    if (!strncmp(namepid, fichier->d_name, 6)) {
                        strcpy(finalfile, PidDir);
                        strcat(finalfile, separetepath);
                        strcat(finalfile, fichier->d_name);
                        if ((f = fopen(finalfile, "rb")) != NULL) {
                            fgets(buff, sizeof(buff), f);
                            fclose(f);
                            int pid = atoi(buff);
                            kill(pid, SIGUSR2);
                            finalfile[0] = '\0';
                        }
                    }
                }
            }
            sleep(1);
            fprintf(stderr, "\b");
            fprintf(stderr, "/");
            sleep(1);
            fprintf(stderr, "\b");
            fprintf(stderr, "-");
            sleep(1);
            fprintf(stderr, "\b");
            fprintf(stderr, "DONE");
        }
        return 0;
    }

    return 0;
}

