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

/**
 * redirec_entrada - Redirige la entrada estándar desde un archivo.
 * 
 * @args: Arreglo de argumentos de la orden.
 * @indice_entrada: Índice donde se encuentra el operador de redirección de entrada (<).
 * 
 * Esta función abre el archivo especificado después del operador < y redirige la entrada
 * estándar (stdin) hacia ese archivo. Además, elimina los argumentos relacionados con
 * la redirección del arreglo de argumentos.
 */
void redirec_entrada(char **args, int indice_entrada) {
    int fd = open(args[indice_entrada + 1], O_RDONLY);
    if (fd == -1) {
        printf("Error al abrir archivo para entrada");
        exit(EXIT_FAILURE);
    }
    if (dup2(fd, STDIN_FILENO) == -1) {
        printf("Error al redirigir entrada");
        close(fd);
        exit(EXIT_FAILURE);
    }
    close(fd);
    args[indice_entrada] = NULL;
    args[indice_entrada + 1] = NULL;
}

/**
 * redirec_salida - Redirige la salida estándar o errores a un archivo.
 * 
 * @args: Arreglo de argumentos de la orden.
 * @indice_salida: Índice donde se encuentra el operador de redirección de salida (> o >> o >2).
 * 
 * Esta función abre el archivo especificado después del operador de redirección y redirige la
 * salida estándar (stdout) o errores (stderr) según corresponda. Además, elimina los argumentos
 * relacionados con la redirección del arreglo de argumentos.
 */
void redirec_salida(char **args, int indice_salida) {
    int fd;

    if (strcmp(args[indice_salida], ">>") == 0) {
        // Abrir archivo en modo de agregar (append).
        fd = open(args[indice_salida + 1], O_WRONLY | O_CREAT | O_APPEND, 0644);
    } else if (strcmp(args[indice_salida], ">2") == 0) {
        // Redirección de errores estándar y salida a un archivo
        fd = open(args[indice_salida + 1], O_WRONLY | O_CREAT | O_TRUNC, 0644);
        if (fd == -1) {
            perror("Error al abrir archivo para redirección de errores");
            exit(EXIT_FAILURE);
        }

        // Redirigir tanto la salida estándar (stdout) como los errores (stderr)
        if (dup2(fd, STDOUT_FILENO) == -1 || dup2(fd, STDERR_FILENO) == -1) {
            perror("Error al redirigir salida y errores");
            close(fd);
            exit(EXIT_FAILURE);
        }
        close(fd);
        return; // No continuar con las otras verificaciones de redirección
    } else {
        // Comportamiento por defecto: sobrescribir salida estándar.
        fd = open(args[indice_salida + 1], O_WRONLY | O_CREAT | O_TRUNC, 0644);
    }

    if (fd == -1) {
        perror("Error al abrir archivo para redirección");
        exit(EXIT_FAILURE);
    }

    // Redirigir la salida estándar (si no se usó >2 para ambos)
    if (strcmp(args[indice_salida], ">2") == 0) {
        if (dup2(fd, STDERR_FILENO) == -1) {
            perror("Error al redirigir errores");
            close(fd);
            exit(EXIT_FAILURE);
        }
    } else {
        if (dup2(fd, STDOUT_FILENO) == -1) {
            perror("Error al redirigir salida");
            close(fd);
            exit(EXIT_FAILURE);
        }
    }

    close(fd);

    // Eliminar la redirección de los argumentos.
    args[indice_salida] = NULL;
    args[indice_salida + 1] = NULL;
}
