/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   u_vars.c                                           :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: rbousset <marvin@42.fr>                    +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2020/02/14 17:19:27 by rbousset          #+#    #+#             */
/*   Updated: 2020/02/14 17:19:29 by rbousset         ###   ########lyon.fr   */
/*                                                                            */
/* ************************************************************************** */

#include <libft.h>
#include <stdlib.h>
#include <stdint.h>

#include "d_define.h"
#include "f_fail.h"
#include "s_destroy.h"
#include "s_line.h"
#include "s_struct.h"
#include "u_utils.h"

static char
	*u_dup_env(char *p_env,
			t_msh *msh)
{
	char	*varval;

	if (!(varval = ft_strdup(p_env)))
	{
		f_alloc_and_destroy_msh(msh);
	}
	return (varval);
}

static char
	*u_get_frm_env(const char varname[],
				t_msh *msh)
{
	char	**env_dup;
	char	*pp_env;
	char	*varval;
	size_t	i;

	env_dup = u_get_env_var_names(msh);
	i = 0;
	while (env_dup[i] != NULL)
	{
		if (ft_strncmp(varname + 1, env_dup[i], ft_strlen(env_dup[i]) + 1) == 0)
		{
			pp_env = msh->envp[i];
			while (*pp_env != '\0' && *pp_env != '=')
				pp_env += 1;
			if (*pp_env == '=')
				pp_env += 1;
			varval = u_dup_env(pp_env, msh);
			ft_delwords(env_dup);
			return (varval);
		}
		i++;
	}
	ft_delwords(env_dup);
	return (NULL);
}

static char
	*u_get_special_var(const char varname[],
					t_msh *msh)
{
	char	*varval;

	if (ft_strncmp(varname, FT_RET_VAR, 3) == 0)
	{
		if ((varval = ft_uitoa(msh->ret)) == NULL)
		{
			f_alloc_and_destroy_msh(msh);
		}
		return (varval);
	}
	else if (ft_strncmp(varname, FT_ZER_VAR, 3) == 0)
	{
		if ((varval = ft_strdup(msh->shname)) == NULL)
		{
			f_alloc_and_destroy_msh(msh);
		}
		return (varval);
	}
	return (NULL);
}

char
	*u_get_cstm_vr(const char varname[],
				t_msh *msh)
{
	t_lvars	*ptr;
	char	*varval;

	ptr = msh->vars;
	while (ptr != NULL &&
		ft_strncmp(varname + 1, ptr->name, ft_strlen(varname + 1) + 1) != 0)
	{
		ptr = ptr->next;
	}
	if (ptr != NULL)
	{
		if (!(varval = ft_strdup(ptr->val)))
		{
			f_alloc_and_destroy_msh(msh);
		}
		return (varval);
	}
	else
	{
		return (NULL);
	}
}

/*
** char*
** u_get_var_value(const char varname[], t_msh *msh);
**
** DESCRIPTION
** The u_get_var_value() function returns
** a heap-allocated, null-terminated string
** that may later be free'd containing the
** value of the variable varname[] including
** the '$' prefix. NULL is returned if varname[]
** wasn't found.
*/

char
	*u_get_var_value(const char varname[],
					t_msh *msh)
{
	/* TODO: check behaviour on empty vars -> "QWE=" */
	char	*varval;

	varval = NULL;
	if ((varval = u_get_special_var(varname, msh)) != NULL)
	{
		return (varval);
	}
	else if ((varval = u_get_cstm_vr(varname, msh)) != NULL)
	{
		return (varval);
	}
	else
	{
		varval = u_get_frm_env(varname, msh);
		return (varval);
	}
	return (NULL);
}