/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   find_access.c                                      :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: lperrey <lperrey@student.42.fr>            +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2021/11/16 01:57:38 by lperrey           #+#    #+#             */
/*   Updated: 2021/11/30 13:37:09 by lperrey          ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include "minishell.h"

static int			search_cmd_path(char *cmd_name, char **cmd_path,
					char *path[]);
static t_builtin_f	search_builtin(char *cmd_name);
static int			handle_access_error(char *file_name);

// https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_08_02
// faire des test sur la valeur de errno selon les cas (if directory, if pathname invalid, ...)

int	cmd_find_access(t_cmd *cmd, char *path[])
{
	if (ft_strchr(cmd->argv[0], '/'))
	{
		if (access(cmd->argv[0], X_OK) == -1)
			cmd->error = handle_access_error(cmd->argv[0]);
		else
		{
			cmd->path = ft_strdup(cmd->argv[0]);
			if (!cmd->path) 
				return (0);
		}
	}
	else
	{
		cmd->builtin_func = search_builtin(cmd->argv[0]);
		if (cmd->builtin_func)
			return (1);
		if (search_cmd_path(cmd->argv[0], &cmd->path, path) == -1)
			return (0);
		if (!cmd->path)
		{
			cmd->error = EXIT_CMD_NOT_FOUND;
			ft_putstr_fd("minishell: ", 2);
			ft_putstr_fd(cmd->argv[0], 2);
			ft_putstr_fd(": command not found\n", 2);
		}
	}
	return (1);
}


static int	search_cmd_path(char *cmd_name, char **cmd_path, char *path[])
{
	int	i;

	if (!path)
		return (1);
	cmd_name = ft_strjoin("/", cmd_name);
	if (!cmd_name)
		return (ft_reti_perror(-1, "search_cmd_path()"));
	i = 0;
	while (path[i])
	{
		*cmd_path = ft_strjoin(path[i], cmd_name);
		if (!*cmd_path)
			return (ft_reti_perror(-1, "search_cmd_path()"));
		if (access(*cmd_path, X_OK) == 0)
			break ;
		else
			ft_free_null(cmd_path);
		i++;
	}
	free(cmd_name);
	return (1);
}

static t_builtin_f	search_builtin(char *cmd_name)
{
	if (ft_strncmp(cmd_name, "echo", 4 + 1) == 0)
		return (&builtin_echo);
	else if (ft_strncmp(cmd_name, "cd", 2 + 1) == 0)
		return (&builtin_cd);
	else if (ft_strncmp(cmd_name, "pwd", 3 + 1) == 0)
		return (&builtin_pwd);
	else if (ft_strncmp(cmd_name, "export", 6 + 1) == 0)
		return (&builtin_export);
	else if (ft_strncmp(cmd_name, "unset", 5 + 1) == 0)
		return (&builtin_unset);
	else if (ft_strncmp(cmd_name, "env", 3 + 1) == 0)
		return (&builtin_env);
	else if (ft_strncmp(cmd_name, "exit", 4 + 1) == 0)
		return (&builtin_exit);
	return (NULL);
}

static int	handle_access_error(char *file_name)
{
	int	tmp;

	tmp = errno;
	ft_perror_io("minishell: ", file_name);
	errno = tmp;
	if (errno == EACCES)
		return (EXIT_CMD_NOT_FOUND);
	return (1);
	// 126 / EXIT_CMD_NOT_EXE
}
