/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   export.c                                           :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: lperrey <lperrey@student.42.fr>            +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2021/12/03 13:36:54 by lperrey           #+#    #+#             */
/*   Updated: 2021/12/06 03:19:30 by lperrey          ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include "minishell.h"

static int	change_var_value(char *arg, char *var_name);

#define ERR_ID 1
#define ERR_ID_STR ": not a valid identifier"
#define CMD "builtin_export"

int	builtin_export(int argc, char *argv[], t_all *c)
{
	int	i;
	int	exit_value;
	int	ret;

	(void)argc;
	exit_value = EXIT_SUCCESS;
	i = 1;
	while (argv[i])
	{
		ret = export_var(argv[i]);
		if (ret == -1)
			return (ft_reti_perror(EXIT_FAILURE, CMD", export_var()"));
		else if (ret == ERR_ID)
			exit_value = EXIT_FAILURE;
		if (ft_strncmp(argv[i], "PATH=", 5) == 0)
			c->path = retrieve_path();
		i++;
	}
	return (exit_value);
}

// in complete shell, must mark arguments for export
// (Not implemented in minishell)
// arg == var_name[=value]
// return "-1" on alloc error 
int	export_var(char *arg)
{
	char	**var_split;
	int		ret;

	ret = 0;
	var_split = ft_split(arg, '=');
	if (!var_split)
		return (-1);
	if (!ft_is_posix_name(var_split[0]))
	{
		shell_error("export: ", var_split[0], ERR_ID_STR, 0);
		ft_free_2d_arr(var_split);
		return (ERR_ID);
	}
	if (ft_strchr(arg, '='))
		ret = change_var_value(arg, var_split[0]);
	ft_free_2d_arr(var_split);
	return (ret);
}

static int	change_var_value(char *arg, char *var_name)
{
	int		env_position;
	char	*tmp;

	env_position = ft_getenv_position(var_name);
	if (environ[env_position] == NULL)
	{
		environ = ft_resize_2d_arr(environ, 1);
		if (!environ)
			return (ft_reti_perror(-1, CMD", ft_resize_2d_arr()"));
	}
	tmp = ft_strdup(arg);
	if (!tmp)
		return (ft_reti_perror(-1, CMD", ft_strdup()"));
	free(environ[env_position]);
	environ[env_position] = tmp;
	return (EXIT_SUCCESS);
}

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