#include "philo.h"

t_philo	*lst_add_philo(t_params *params, t_global *global, int i)
{
	t_philo	*new;

	new = malloc(sizeof(t_philo) * 1);
	if (new == NULL)
		return (NULL);
	new->params = params;
	new->global = global;
	new->p_nbr = i + 1;
	if (pthread_mutex_init(&(new->m_fork), NULL) != 0)
		return (NULL);
	new->t_last_meal.ts = 0;
	new->t_last_meal.tu = 0;
	new->eat = 0;
	new->next = NULL;
	return (new);
}

t_philo	*init_chain_philo(t_params *params, t_global *global)
{
	t_philo	*philo;
	t_philo	*tmp;
	t_philo	*start;
	int		i;

	i = 0;
	philo = NULL;
	while (i < params->n_phi)
	{
		tmp = lst_add_philo(params, global, i);
		if (philo)
			philo->next = tmp;
		else
			start = tmp;
		philo = tmp;
		i++;
	}
	philo->next = start;
	return (philo);
}

t_params	*init_params(int ac, char **av)
{
	t_params	*params;

	if (ac == 5 || ac == 6)
	{
		params = malloc(sizeof(t_params));
		if (!params)
			return (NULL);
		params->n_phi = ft_atoi(av[1]);
		params->t_die = ft_atoi(av[2]);
		params->t_eat = ft_atoi(av[3]);
		params->t_slp = ft_atoi(av[4]);
		params->n_eat = -1;
		if (ac == 6)
			params->n_eat = ft_atoi(av[5]);
	}
	else
		return (NULL);
	return (params);
}

t_global	*init_global(void)
{
	t_global	*global;

	global = malloc(sizeof(t_global));
	if (!global)
		return (NULL);
	global->dead = 0;
	global->n_eat = 0;
	global->t_start.ts = 0;
	global->t_start.tu = 0;
	if (pthread_mutex_init(&(global->m_print), NULL) != 0)
		return (NULL);
	if (pthread_mutex_init(&(global->m_dead), NULL) != 0)
		return (NULL);
	return (global);
}

t_philo	*init(int ac, char **av, pthread_t **id)
{
	t_philo		*philo;
	t_params	*params;
	t_global	*global;

	params = init_params(ac, av);
	if (params == NULL)
		return (NULL);
	global = init_global();
	if (params == NULL)
		return (NULL);
	*id = malloc(sizeof(pthread_t) * params->n_phi);
	if (*id == NULL)
		return (NULL);
	philo = init_chain_philo(params, global);
	if (philo == NULL)
		return (NULL);
	return (philo);
}
