/*
 * Queue - A Queueing system that can be used to handle labs in higher education
 * Copyright (C) 2016-2024  Delft University of Technology
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
package nl.tudelft.queue.service;

import static java.time.LocalDateTime.now;
import static nl.tudelft.queue.misc.QueueSessionStatus.*;
import static nl.tudelft.queue.misc.QueueSessionStatus.OPEN;

import org.springframework.stereotype.Service;

import lombok.AllArgsConstructor;
import nl.tudelft.labracore.api.dto.SessionDetailsDTO;
import nl.tudelft.queue.misc.QueueSessionStatus;
import nl.tudelft.queue.model.QueueSession;
import nl.tudelft.queue.model.labs.AbstractSlottedLab;
import nl.tudelft.queue.model.labs.CapacitySession;
import nl.tudelft.queue.model.labs.RegularLab;

@Service
@AllArgsConstructor
public class LabStatusService {

	private final SessionService sessionService;

	/**
	 * Checks whether the given lab is open to enqueueing of students. This could check whether the lab slot
	 * is open or whether slot selection for the lab is open.
	 *
	 * @param  qSession The lab to check.
	 * @return          Whether the lab is open to enqueueing.
	 */
	public QueueSessionStatus getStatus(QueueSession<?> qSession) {
		if (qSession.getEnqueueClosed()) {
			return GENERIC_CLOSED;
		}

		SessionDetailsDTO session = sessionService.getCoreSession(qSession.getSession());

		if (session.getEndTime().isBefore(now())) {
			return FINISHED_SESSION;
		} else if (qSession instanceof RegularLab &&
				now().isBefore(session.getStart())) {
			return INACTIVE_SESSION;
		} else if (qSession instanceof AbstractSlottedLab<?> &&
				now().isBefore(
						((AbstractSlottedLab<?>) qSession).getSlottedLabConfig().getSelectionOpensAt())) {
			return SLOT_SELECTION_CLOSED;
		} else if (qSession instanceof CapacitySession &&
				(((CapacitySession) qSession).getCapacitySessionConfig().getEnrolmentClosesAt()
						.isBefore(now())
						|| now().isBefore(((CapacitySession) qSession).getCapacitySessionConfig()
								.getEnrolmentOpensAt()))) {
			return ENROLMENT_CLOSED;
		}

		return OPEN;
	}

}
