#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <wait.h>

int main() {
    printf("Parent PID: [%d]\n", getpid()); // Initial parent
    if (fork() == 0) { // Forking child
        printf("Child PID: [%d]\n", getpid());
        int to_lowercase[2];
        pipe(to_lowercase);
        if (fork() == 0) { // Forking grandchild
            printf("Grandchild PID: [%d]\n", getpid());
            char output[100];
            read(to_lowercase[0], output, 100); // Reading from pipe
            close(to_lowercase[0]); // Closing read pipe
            for (int i = 0; i < 100; i++) { // Converting to lowercase using ASCII
                if (output[i] >= 'A' && output[i] <= 'Z') {
                    output[i] += 32;
                }
            }
            printf("%s", output);
            printf("Grandchild PID: [%d]\n", getpid());
            exit(EXIT_SUCCESS);
        } else { // Child
            char input[100];
            fgets(input, 100, stdin); // Input
            write(to_lowercase[1], input, 100); // Writing to pipe
            close(to_lowercase[1]); // Closing write pipe
            wait(NULL);
            printf("Grandchild PID: [%d]\n", getpid());
            exit(EXIT_SUCCESS);
        }
    } else { // Parent
        wait(NULL);
        printf("Parent PID: [%d]\n", getpid());
    }
    exit(EXIT_SUCCESS);
}