/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   expand_token.c                                     :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: lperrey <lperrey@student.42.fr>            +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2021/11/07 02:01:33 by lperrey           #+#    #+#             */
/*   Updated: 2021/12/10 10:27:50 by hulamy           ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include "minishell.h"

static t_list	*ret_parameter_expansion(char *content, int *i);

t_list	*expand_token(char *content)
{
	int		in_quotes;
	int		i;
	int		i_exp;
	t_list	head;
	t_list	*expand;

	in_quotes = 0;
	i = 0;
	head.next = NULL;
	expand = &head;
	while (content[i])
	{
		if (content[i] == '$')
		{
			expand->next = ret_parameter_expansion(content, &i);
			expand = expand->next;
			if (!expand)
			{//todo wrap
				perror("expand_token() error");
				return (ft_lstclear(&head.next, free));
			}
		}
		else
		{
			expand->next = ft_lstnew_generic(sizeof(t_list), ft_strlen(&content[i]) + 1);
			expand = expand->next;
			i_exp = 0;
			if (!expand)
			{//todo wrap
				perror("expand_token() error");
				return (ft_lstclear(&head.next, free));
			}
			while (content[i] && (content[i] != '$' || in_quotes == IN_QUOTES))
			{
				// quoting
				if (content[i] == '\'' && in_quotes != IN_DQUOTES)
				{
					if (in_quotes == IN_QUOTES)
						in_quotes = 0;
					else
						in_quotes = IN_QUOTES;
				}
				((char *)expand->content)[i_exp++] = content[i++];
			}
		}
	}
	return (head.next);
}

// a voir si je retourne pas plutot un "char *".
// Malloc la lst dans la fonction est peut-être un peu superflu et pas super clair.
static t_list	*ret_parameter_expansion(char *content, int *i)
{
	t_list	*expand;
	char	*tmp;
	int		i_tmp;

	tmp = ft_calloc(ft_strlen(&content[*i]) + 1, 1);
	if (!tmp)
		return (NULL);
	expand = ft_lstnew(NULL);
	if (!expand)
		return (ft_retp_free(NULL, tmp, free));
	(*i)++; // skip '$'
	if (content[*i] == '?')
	{
		(*i)++;
		expand->content = ft_itoa(get_last_exit_status());
		return (ft_retp_free(expand, tmp, free));
	}
	else if (content[*i] != '_' && !ft_isalpha(content[*i]))
	{
		tmp[0] = '$';
		expand->content = tmp;
		return (expand);
	}
	i_tmp = 0;
	while (content[*i] == '_' || ft_isalnum(content[*i]))
		tmp[i_tmp++] = content[(*i)++];
	expand->content = getenv(tmp);
	free(tmp);
	if (expand->content)
		expand->content = ft_strdup(expand->content);
	return (expand);
}

/*
environment variables must be POSIX NAME :
	3.235 Name
https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html
#tag_03_235
*/
