#include "minishell.h"

static int open_redir(t_redir *r)
{
	if (r->type == REDIR_IN)
		return open(r->target, O_RDONLY);
	if (r->type == REDIR_OUT)
		return open(r->target, O_WRONLY | O_CREAT | O_TRUNC, 0644);
	if (r->type == REDIR_APPEND)
		return open(r->target, O_WRONLY | O_CREAT | O_APPEND, 0644);
	return -1;
}

int prepare_heredocs(t_pipeline *p, t_shell *sh)
{
	size_t i;

	g_signal = 0;
	for (i = 0; i < p->count; i++)
	{
		t_redir *r = p->cmds[i]->redirs;
		while (r)
		{
			if (r->type == REDIR_HEREDOC)
			{
				int fds[2];
				char *line;
				ms_set_heredoc_signals();
				if (pipe(fds) == -1)
					return 1;
				while (1)
				{
					line = readline("> ");
					if (!line)
						break;
					if (strcmp(line, r->target) == 0)
					{
						free(line);
						break;
					}
					write(fds[1], line, strlen(line));
					write(fds[1], "\n", 1);
					free(line);
				}
				close(fds[1]);
				r->fd = fds[0];
				ms_setup_signals(sh);
				if (g_signal == SIGINT)
				{
					sh->exit_status = 130;
					return 1;
				}
			}
			r = r->next;
		}
	}
	return 0;
}

int apply_redirections(t_command *cmd, int *saved_stdin, int *saved_stdout)
{
	t_redir *r = cmd->redirs;
	*saved_stdin = -1;
	*saved_stdout = -1;
	while (r)
	{
		int fd = -1;
		if (r->type == REDIR_HEREDOC)
			fd = r->fd;
		else
			fd = open_redir(r);
		if (fd == -1)
		{
			perror(r->target);
			return 1;
		}
		if (r->type == REDIR_IN || r->type == REDIR_HEREDOC)
		{
			if (*saved_stdin == -1)
				*saved_stdin = dup(STDIN_FILENO);
			dup2(fd, STDIN_FILENO);
		}
		else
		{
			if (*saved_stdout == -1)
				*saved_stdout = dup(STDOUT_FILENO);
			dup2(fd, STDOUT_FILENO);
		}
		if (r->type != REDIR_HEREDOC)
			close(fd);
		r = r->next;
	}
	return 0;
}

void restore_redirections(int saved_stdin, int saved_stdout)
{
	if (saved_stdin != -1)
	{
		dup2(saved_stdin, STDIN_FILENO);
		close(saved_stdin);
	}
	if (saved_stdout != -1)
	{
		dup2(saved_stdout, STDOUT_FILENO);
		close(saved_stdout);
	}
}
