#include "minishell.h"

static t_env *env_new(const char *key, const char *value)
{
	t_env *n = (t_env *)calloc(1, sizeof(t_env));
	if (!n)
		return NULL;
	n->key = ms_strdup(key);
	n->value = value ? ms_strdup(value) : ms_strdup("");
	if (!n->key || !n->value)
	{
		free(n->key);
		free(n->value);
		free(n);
		return NULL;
	}
	return n;
}

void env_init(t_shell *sh, char **envp)
{
	int i;
	char *eq;

	sh->env = NULL;
	if (!envp)
		return;
	i = 0;
	while (envp[i])
	{
		eq = strchr(envp[i], '=');
		if (eq)
		{
			char *key = ms_strndup(envp[i], (size_t)(eq - envp[i]));
			char *val = ms_strdup(eq + 1);
			env_set(sh, key, val);
			free(key);
			free(val);
		}
		i++;
	}
}

void env_clear(t_shell *sh)
{
	t_env *cur = sh->env;
	t_env *next;

	while (cur)
	{
		next = cur->next;
		free(cur->key);
		free(cur->value);
		free(cur);
		cur = next;
	}
	sh->env = NULL;
}

char *env_get(t_shell *sh, const char *key)
{
	t_env *cur = sh->env;

	while (cur)
	{
		if (strcmp(cur->key, key) == 0)
			return cur->value;
		cur = cur->next;
	}
	return NULL;
}

int env_set(t_shell *sh, const char *key, const char *value)
{
	t_env *cur = sh->env;
	t_env *prev = NULL;

	while (cur)
	{
		if (strcmp(cur->key, key) == 0)
		{
			char *dup = ms_strdup(value ? value : "");
			if (!dup)
				return 1;
			free(cur->value);
			cur->value = dup;
			return 0;
		}
		prev = cur;
		cur = cur->next;
	}
	cur = env_new(key, value);
	if (!cur)
		return 1;
	if (prev)
		prev->next = cur;
	else
		sh->env = cur;
	return 0;
}

int env_unset(t_shell *sh, const char *key)
{
	t_env *cur = sh->env;
	t_env *prev = NULL;

	while (cur)
	{
		if (strcmp(cur->key, key) == 0)
		{
			if (prev)
				prev->next = cur->next;
			else
				sh->env = cur->next;
			free(cur->key);
			free(cur->value);
			free(cur);
			return 0;
		}
		prev = cur;
		cur = cur->next;
	}
	return 0;
}

char **env_to_envp(t_shell *sh)
{
	char **envp;
	int count = 0;
	t_env *cur = sh->env;
	int i = 0;

	while (cur)
	{
		count++;
		cur = cur->next;
	}
	envp = (char **)calloc((size_t)count + 1, sizeof(char *));
	if (!envp)
		return NULL;
	cur = sh->env;
	while (cur)
	{
		char *kv = ms_strjoin3(cur->key, "=", cur->value);
		envp[i++] = kv;
		cur = cur->next;
	}
	envp[i] = NULL;
	return envp;
}

void env_free_envp(char **envp)
{
	int i = 0;
	if (!envp)
		return;
	while (envp[i])
		free(envp[i++]);
	free(envp);
}

void env_print(t_shell *sh)
{
	t_env *cur = sh->env;
	while (cur)
	{
		if (cur->value)
			printf("%s=%s\n", cur->key, cur->value);
		cur = cur->next;
	}
}
