#include "philo.h"
void set_finished(t_rules *rules)
{
	pthread_mutex_lock(rules->finished_lock);
	rules->finished = 1;
	pthread_mutex_unlock(rules->finished_lock);
}

int get_finished(t_rules *rules)
{
	int finished;

	pthread_mutex_lock(rules->finished_lock);
	finished = rules->finished;
	pthread_mutex_unlock(rules->finished_lock);
	return (finished);
}
void philo_die(t_philo *philo)
{
	print_status(philo, "died");
	philo->death = 1;
	set_finished(philo->rules);
	pthread_mutex_unlock(philo->l_fork);
	pthread_mutex_unlock(philo->r_fork);
}

int philo_died_while_sleeping(t_philo *philo, int time)
{
	const int	start = get_time();
	while(get_time() - start < time)
	{
		if (philo->last_meal - get_time() >= philo->rules->time_to_die)
			return (SUCCESS);
		usleep(500);
	}
	return (FAILURE);
}
int philo_eat(t_philo *philo)
{
	if (philo->id % 2 == 1)
	{
		pthread_mutex_lock(philo->r_fork);
		print_status(philo, "has taken a fork");
	}
	pthread_mutex_lock(philo->l_fork);
	print_status(philo, "has taken a fork");
	if (philo->id % 2 == 0)
	{
		pthread_mutex_lock(philo->r_fork);
		print_status(philo, "has taken a fork");
	}	
	if (check_death(philo))
		return (philo_die(philo), FAILURE);
	print_status(philo, "is eating");
	philo->last_meal = get_time();
	philo->n_eat++;
	return (SUCCESS);
}

void	*philo_routine(void *arg)
{
	t_philo	*philo;

	philo = (t_philo *)arg;

	while (get_time() < philo->rules->start_time)
		usleep(50);
	while (!philo->death && !philo->rules->finished 
		&& (philo->n_eat < philo->rules->n_must_eat || philo->rules->n_must_eat == -1))
	{

		if (check_death(philo))
			return (philo_die(philo), NULL);
		if (!philo_eat(philo))
			return (NULL);
		if (philo_died_while_sleeping(philo, philo->rules->time_to_eat))
			return (philo_die(philo), NULL);
		pthread_mutex_unlock(philo->l_fork);
		pthread_mutex_unlock(philo->r_fork);
		print_status(philo, "is sleeping");
		if (philo_died_while_sleeping(philo, philo->rules->time_to_sleep))
			return (philo_die(philo), NULL);
		print_status(philo, "is thinking");
	}
	return (NULL);
}