/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   ft_get_executable.c                                :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: cchauvet <cchauvet@student.42angouleme.fr  +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2023/03/27 13:39:48 by cchauvet          #+#    #+#             */
/*   Updated: 2023/03/30 13:04:53 by cchauvet         ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include "./utils.h"
#include <unistd.h>

char	*ft_get_executable_with_path(t_data *data, const char *name)
{
	char	*path;

	if (access(name, F_OK) != 0)
	{
		data->exit_code = 127;
		ft_eprintf("minishell: %s: No such file or directery\n", name);
		return (NULL);
	}
	if (access(name, X_OK) != 0)
	{
		data->exit_code = 126;
		ft_eprintf("minishell: %s: permission denied\n", name);
		return (NULL);
	}
	path = ft_strdup(name);
	if (path == NULL)
	{
		ft_eprintf("minishell: malloc failed\n");
		return (NULL);
	}
	return (path);
}

static char	**ft_get_paths(t_data *data, const char *name)
{
	char	*paths;
	char	**tab;

	paths = get_value_by_key("PATH", data->env);
	if (paths == NULL)
	{
		data->exit_code = 127;
		ft_eprintf("minishell: %s: command not found\n", name);
		return (NULL);
	}
	tab = ft_split(paths, ':');
	if (tab == NULL)
	{
		ft_eprintf("minishell: malloc failed\n");
		return (NULL);
	}
	return (tab);
}

static char	*ft_file_is_executable(const char *path, const char *name)
{
	char	*out;

	out = ft_strmerger(3, path, "/", name);
	if (out == NULL)
	{
		ft_eprintf("minishell: malloc failed\n");
		free(out);
		return (NULL);
	}
	if (access(out, X_OK) == 0)
		return (out);
	free(out);
	return (NULL);
}

static char	*ft_get_executable_without_path(t_data *data, const char *name)
{
	char	**paths;
	char	*path;
	size_t	i;

	paths = ft_get_paths(data, name);
	if (paths == NULL)
		return (NULL);
	path = NULL;
	i = 0;
	while (paths[i] != NULL)
	{
		path = ft_file_is_executable(paths[i], name);
		if (path != NULL)
			break ;
		i++;
	}
	ft_freer_tab_ultimate(1, paths);
	if (path == NULL)
	{
		data->exit_code = 127;
		ft_eprintf("minishell: %s: command not found\n", name);
	}
	return (path);
}

char	*ft_get_executable(t_data *data, const char *name)
{
	char	*path;

	if (name[0] == '.' || name[0] == '/')
		path = ft_get_executable_with_path(data, name);
	else
		path = ft_get_executable_without_path(data, name);
	return (path);
}
