#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <string.h>

int main(int argc, char* argv[]) {
    // Validamos que se pase el número de procesos N por argumento
    if (argc < 2) {
        fprintf(stderr, "Error: Debe indicar el número de procesos (N).\n");
        fprintf(stderr, "Uso: %s <N>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    int N = atoi(argv[1]);
    int status;
    pid_t pid;

    printf("--- INICIO DE CADENA (Padre Raíz PID: %d) ---\n", getpid());

    for (int i = 1; i <= N; i++) {
        pid = fork();

        switch (pid) {
            case -1:
                perror("Error en fork");
                exit(EXIT_FAILURE);

            case 0:
                // CÓDIGO DEL HIJO
                printf("Soy el hijo %d (PID: %d). Mi padre es: %d\n", i, getpid(), getppid());
                
                // Si aún no hemos llegado al final de la cadena (N), 
                // el hijo continúa el bucle para crear a su propio hijo.
                if (i < N) {
                    continue; 
                } else {
                    // El último proceso de la cadena imprime y termina
                    printf("Último proceso (%d) alcanzado. Finalizando...\n", i);
                    exit(0);
                }

            default:
                // CÓDIGO DEL PADRE
                // Cada padre espera a su hijo directo para asegurar la fila
                waitpid(pid, &status, 0);
                
                if (WIFEXITED(status)) {
                    printf("Padre (PID: %d) recogió a su hijo (PID: %d) con status %d\n", 
                            getpid(), pid, WEXITSTATUS(status));
                }
                
                // Una vez recogido el hijo, el padre debe salir para no seguir el bucle
                exit(0); 
        }
    }

    return 0;
}