#include <stdlib.h>
#include <unistd.h>
#include "xfunc.h"
#include "libmy.h"
#include "get_next.h"

static int	my_get_size(t_buff *stack)
{
  int		res;

  res = 0;
  while (stack)
    {
      res += stack->size;
      stack = stack->next;
    }
  return (res);
}

static char	*my_pop(t_buff **stack)
{
  int		size;
  char		*res;
  t_buff	*tmp;

  res = NULL;
  if ((size = my_get_size(*stack))
      && (res = xmalloc((size + 1) * sizeof(*res))))
    {
      res[size] = '\0';
      while (*stack)
	{
	  size = my_get_size(*stack);
	  my_strncpy(res + (size - (*stack)->size),
		     (*stack)->str, (*stack)->size);
	  tmp = *stack;
	  *stack = (*stack)->next;
	  free(tmp->str);
	  free(tmp);
	}
    }
  return (res);
}

static int	my_push(t_buff **stack, char *str, int size)
{
  t_buff	*new;

  if (size > 0)
    if ((new = xmalloc(sizeof(*new))))
      if ((new->str = xmalloc(size * sizeof(*(new->str)))))
	{
	  new->size = size;
	  my_strncpy(new->str, str, size);
	  if (*stack)
	    new->next = *stack;
	  else
	    new->next = NULL;
	  *stack = new;
	  return (size);
	}
  return (0);
}

static char	*verif(const int fd, t_buff **stack, char *buff, int str_size)
{
  if (str_size > 0 && my_push(stack, buff, str_size))
    return (get_next_line(fd));
  else
    return (my_pop(stack));
}

char		*get_next_line(const int fd)
{
  int		i;
  char		*res;
  static t_buff *stack;
  int		tot_size;
  int		str_size;
  char		buff[BUF_SIZE];

  if ((i = 0) || stack)
    while (i < stack->size)
      if (stack->str[i++] == '\n')
	{
	  str_size = stack->size;
	  tot_size = my_get_size(stack) - str_size;
	  res = my_pop(&stack);
	  my_push(&stack, res + tot_size + i, str_size - i);
	  res[tot_size + i - 1] = '\0';
	  return (res);
	}
  if ((str_size = read(fd, buff, BUF_SIZE)) != (-1))
    return (verif(fd, &stack, buff, str_size));
  free(my_pop(&stack));
  return (NULL);
}