/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   generic.c                                          :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: lperrey <lperrey@student.42.fr>            +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2021/10/08 09:25:35 by lperrey           #+#    #+#             */
/*   Updated: 2021/12/10 10:28:48 by hulamy           ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include "minishell.h"

char	*ft_strjoinfree(char *s1, char *s2)
{
	char	*str;

	str = ft_strjoin(s1, s2);
	free(s1);
	free(s2);
	return (str);
}

char	*ft_strjoinfree_s1(char *s1, const char *s2)
{
	char	*str;

	str = ft_strjoin(s1, s2);
	free(s1);
	return (str);
}

char	*ft_strjoinfree_s2(const char *s1, char *s2)
{
	char	*str;

	str = ft_strjoin(s1, s2);
	free(s2);
	return (str);
}

void	ft_lstprint(t_list *lst, int fd)
{
	while (lst)
	{
		ft_putendl_fd(lst->content, fd);
		lst = lst->next;
	}
}

int	ft_isinset_str(char *str, char *set)
{
	size_t	i;
	size_t	i_set;
	int		valid;

	i = 0;
	while (str[i])
	{
		valid = 0;
		i_set = 0;
		while (set[i_set] && !valid)
		{
			if (str[i] == set[i_set])
				valid = 1;
			i_set++;
		}
		if (!valid)
			return (0);
		i++;
	}
	return (i);
}

size_t	ft_2d_arrlen(void *ptr) // Replace ft_arrlen()
{
	size_t	len;
	char	**arr;

	arr = (char **)ptr;
	len = 0;
	while (arr[len] != NULL)
		len++;
	return (len);
}
/* 
char	**ft_dup_2d_char_arr(char **ptr) // Superflu si ft_dup_2d_arr() fonctionne
{
	unsigned int	i;
	char			**arr;
	char			**new_arr;

	new_arr = malloc((ft_2d_arrlen(ptr) + 1) * sizeof (void *));
	if (!new_arr)
		return (NULL);
	arr = (char **)ptr;
	i = 0;
	while (arr[i])
	{
		new_arr[i] = ft_strdup(arr[i]);
		if (!new_arr[i])
			return (ft_retp_free(NULL, new_arr, ft_free_2d_arr));
		i++;
	}
	new_arr[i] = NULL;
	return (new_arr);
} */

// Test generic. Pas certain que ça fonctionne bien avec le pointeur sur fonction
void	*ft_dup_2d_arr(void	*ptr, void *(*dup_func)(void *))
{
	unsigned int	i;
	char			**arr;
	char			**new_arr;

	new_arr = ft_calloc(ft_2d_arrlen(ptr) + 1, sizeof (void *));
	if (!new_arr)
		return (NULL);
	arr = (char **)ptr;
	i = 0;
	while (arr[i])
	{
		new_arr[i] = dup_func(arr[i]);
		if (!new_arr[i])
			return (ft_retp_free(NULL, new_arr, ft_free_2d_arr));
		i++;
	}
	return (new_arr);
}

void	*ft_resize_2d_arr(void *ptr, size_t add_nbr)
{
	unsigned int	i;
	char			**arr;
	char			**new_arr;

	new_arr = ft_calloc(ft_2d_arrlen(ptr) + add_nbr + 1, sizeof (void *));
	if (!new_arr)
		return (NULL);
	arr = (char **)ptr;
	i = 0;
	while (arr[i])
	{
		new_arr[i] = arr[i];
		i++;
	}
	free(arr);
	return (new_arr);
}

// pour imprimer une char ** en precisant comment separer les char *
void	print_matrix(char **matrix, char *sep)
{
	int	i;

	i = 0;
	while (matrix[i])
	{
		printf("%s", matrix[i]);
		if (matrix[i + 1])
			printf("%s", sep);
		fflush(stdout);
		i++;
	}
	write(1, "\n", 1);
}

t_list	*ft_lstbeforelast(t_list *lst)
{
	if (!lst || !lst->next)
		return (NULL);
	while (lst->next->next)
		lst = lst->next;
	return (lst);
}

/* if "content_size == 0", return lst with "lst->content == NULL" */
void	*ft_lstnew_generic(size_t lst_size, size_t content_size)
{
	t_list	*elem;
	void	*content;

	if (content_size == 0)
		content = NULL;
	else
	{
		content = ft_calloc(content_size, 1);
		if (!content)
			return (NULL);
	}
	elem = ft_calloc(1, lst_size);
	if (!elem)
	{
		free(content);
		return (NULL);
	}
	elem->content = content;
	elem->next = NULL;
	return (elem);
}

void	ft_perror_io(char *err_str, char *io_file)
{
	ft_putstr_fd(err_str, 2);
	perror(io_file);
}

int	ft_reti_perror_io(int ret, char *err_str, char *io_file)
{
	ft_putstr_fd(err_str, 2);
	perror(io_file);
	return (ret);
}

void	ft_free_null(void *ptr)
{
	free(*(char**)ptr);
	*(char**)ptr = NULL;
}

/*
** Search for an environement variable,
** and return a pointer to the first character after "env_var=" .
** Return NULL if env_var not found.
*/
char	*ft_getenv(char *env_var)
{
	int		i;
	char	*tmp;
	size_t	env_var_len;

	env_var_len = ft_strlen(env_var);
	i = 0;
	tmp = NULL;
	while (!tmp && environ[i])
	{
		if (environ[i][env_var_len] == '=')
		{
			if (ft_strncmp(environ[i], env_var, env_var_len) == 0)
				tmp = &environ[i][env_var_len + 1];
			else
				i++;
		}
		else
			i++;
	}
	return (tmp);
}

/*
** Like ft_getenv(), but return position of env_var instead of value.
** If env_var not found, return last position of **environ (== NULL)
*/
size_t	ft_getenv_position(char *env_var)
{
	int		i;
	int		found;
	size_t	env_var_len;

	env_var_len = ft_strlen(env_var);
	i = 0;
	found = 0;
	while (!found && environ[i])
	{
		if (environ[i][env_var_len] == '=')
		{
			if (ft_strncmp(environ[i], env_var, env_var_len) == 0)
				found = 1;
			else
				i++;
		}
		else
			i++;
	}
	return (i);
}

int	ft_is_posix_name(char *str)
{
	unsigned int	i;

	if (str[0] != '_' && !ft_isalpha(str[0]))
		return (0);
	i = 1;
	while (str[i])
	{
		if (str[i] != '_' && !ft_isalnum(str[i]))
			return (0);
		i++;
	}
	return (i);
}
