#include "philo.h"

/*
	t_params		*params;
	t_params		*global;
	int				p_nbr;
	t_mtx			m_fork;
	long int		t_last_meal_s;
	long int		t_last_meal_u;
	*/
t_philo	*lst_add_philo(t_params *params, t_mtx *m_print, t_mtx *m_dead, 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->next = NULL;
	return (new);
}

// looping chained list
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]);
		if (ac == 6)
			params->n_eat = ft_atoi(av[5]);
	}
	else
		return (NULL);
	return (params);
}

t_global	*init_global(t_mtx *m_print, t_mtx *m_dead)
{
	t_global	*global;

	global = malloc(sizeof(t_global));
	if (!global)
		return (NULL);
	global->dead = 0;
	global->t_start_s = 0;
	global->t_start_u = 0;
	global->m_print = m_print;
	global->m_dead = m_dead;
	return (global);
}

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

	m_print = malloc(sizeof(t_mtx));
	if (pthread_mutex_init(m_print, NULL) != 0)
		return (NULL);
	m_dead = malloc(sizeof(t_mtx));
	if (pthread_mutex_init(m_dead, NULL) != 0)
		return (NULL);
	params = init_params(ac, av);
	if (params == NULL)
		return (NULL);
	global = init_global(m_print, m_dead);
	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);
}
