/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   caller.c                                           :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: narnaud <narnaud@student.42.fr>            +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2022/05/03 11:48:16 by narnaud           #+#    #+#             */
/*   Updated: 2022/05/06 13:32:33 by narnaud          ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include "minishell.h"

int	builtin_call(t_datas *datas, t_command *cmd)
{
	if (ft_strncmp(cmd->argv[0], "echo", 5) == 0)
		return (ft_echo(cmd));
	else if (ft_strncmp(cmd->argv[0], "pwd", 4) == 0)
		return (ft_pwd(cmd));
	else if (ft_strncmp(cmd->argv[0], "cd", 3) == 0)
		return (ft_cd(cmd));
	else if (ft_strncmp(cmd->argv[0], "export", 7) == 0)
		return (ft_export(datas, cmd));
	else if (ft_strncmp(cmd->argv[0], "unset", 6) == 0)
		return (ft_unset(datas, cmd));
	else if (ft_strncmp(cmd->argv[0], "env", 4) == 0)
		return (ft_env(datas, cmd));
	else if (ft_strncmp(cmd->argv[0], "exit", 5) == 0)
		return (close_minishell(0));
	else
		return (-1);
}


int is_builtin(char *cmd)
{
	if (!ft_strncmp(cmd, "echo", 5) ||
		!ft_strncmp(cmd, "pwd", 4) ||
		!ft_strncmp(cmd, "cd", 3) ||
		!ft_strncmp(cmd, "export", 7) ||
		!ft_strncmp(cmd, "unset", 6) ||
		!ft_strncmp(cmd, "env", 4) ||
		!ft_strncmp(cmd, "exit", 5))
		return (1);
	else
		return (0);
}

void	exe(t_datas *datas, t_command *cmd)
{
	char	**path_dirs;
	char	*path;
	size_t	path_length;

	if (ft_strchr(cmd->argv[0], '/'))
		execve(cmd->argv[0], cmd->argv, datas->envp);
	else
	{
		path_dirs = ft_split(getenv("PATH"), ':');
		while (path_dirs)
		{
			path_length = ft_strlen(*path_dirs) + ft_strlen(cmd->argv[0]) + 2;
			path = ft_calloc(path_length, sizeof(char));
			ft_memcpy(path, *path_dirs, ft_strlen(*path_dirs));
			ft_memcpy(path + ft_strlen(*path_dirs),"/", 1);
			ft_memcpy(path + ft_strlen(*path_dirs) + 1, cmd->argv[0], ft_strlen(cmd->argv[0]));
			execve(path, cmd->argv, datas->envp);
			path_dirs++;
		}
	}
}

pid_t caller(t_datas *datas, t_command *cmd)
{
	pid_t	pid;

	pid = fork();
	if (!pid)
	{	
		if (builtin_call(datas, cmd) == -1)	
		{			
			if (cmd->fd[0])
				dup2(cmd->fd[0], STDIN_FILENO);
			if (cmd->fd[1])
				dup2(cmd->fd[1], STDOUT_FILENO);
			exe(datas, cmd);
		}
		exit(EXIT_SUCCESS);
	}
	return pid;
}

int	piper(t_datas *datas, t_command *cmd)
{
	int		pip[2];
	int 	status;
	pid_t	pid;

	if (cmd->fd[1] == 0 && cmd->next &&  cmd->next->fd[0] == 0)
	{
		pipe(pip);
		cmd->fd[1] = pip[1];
		cmd->next->fd[0] = pip[0];
	}
	pid = caller(datas, cmd);
	if (cmd->fd[1])
		close(cmd->fd[1]);
	if (cmd->next)
		piper(datas, cmd->next);
	waitpid(pid, &status, 0);
	if (!cmd->next)
		handle_status(datas, status);
	if (cmd->fd[0])
		close(cmd->fd[0]);
	return (1);
}