#include <iostream>     // For input and output
#include <unistd.h>    // For fork(), getpid(), getppid(), wait()
#include <sys/types.h> // For pid_t
#include <sys/wait.h>  // For wait()

using namespace std;

int main() {
    pid_t pid;  // Variable to store process ID

    // Print the PID of the main/original process
    cout << "Original Process Started. PID: " << getpid() << endl;

    // Process Creation using fork()
    pid = fork();  // Creates a new child process

    // Check if fork() failed
    if (pid < 0) {
        cerr << "Failed to create child process." << endl;
        return 1;  // Exit with error
    }

    // If fork() returns 0, it means this is the child process
    else if (pid == 0) {
        cout << "This is the Child Process." << endl;
        cout << "Child PID: " << getpid() << ", Parent PID: " << getppid() << endl;

        // Child-specific tasks
        for (int i = 1; i <= 5; i++) {
            cout << "Child Process: Count " << i << endl;
            sleep(1); // Simulate some work with a sleep
        }
    }

    // If fork() returns a positive value, this is the parent process
    else {
        cout << "This is the Parent Process." << endl;
        cout << "Parent PID: " << getpid() << ", Child PID: " << pid << endl;

        // Parent-specific tasks
        for (int i = 1; i <= 3; i++) {
            cout << "Parent Process: Count " << i << endl;
            sleep(2); // Simulate some work with a sleep
        }

        // Wait for the child process to complete
        wait(NULL); // Wait for the child process to finish
        cout << "Child process has completed." << endl;
    }

    return 0;  // End of program
}