/*
 * 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 java.io.*;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import jakarta.transaction.Transactional;
import lombok.AllArgsConstructor;
import nl.tudelft.labracore.lib.security.user.Person;
import nl.tudelft.queue.dto.view.CodeOfConductDTO;
import nl.tudelft.queue.properties.QueueProperties;
import nl.tudelft.queue.repository.ProfileRepository;

@Service
@AllArgsConstructor
public class CodeOfConductService {

	private static final Logger logger = LoggerFactory.getLogger(CodeOfConductService.class);

	private final QueueProperties queueProperties;

	private final ProfileRepository profileRepository;

	private final MarkdownService markdownService;

	/**
	 * Update the last moment the user read the code of conduct.
	 *
	 * @param person The person for which to update.
	 * @param date   The date to which this should be udpated.
	 */
	@Transactional
	public void updateLatestCoC(Person person, LocalDateTime date) {
		profileRepository.findProfileForPerson(person).setLastSeenCoc(date);
	}

	/**
	 * Get the code of conduct information for a person.
	 *
	 * @param  person The person for whom to get the code of conduct.
	 * @return        A DTO which can be send to the front-end containing the last time the user read the code
	 *                of conduct and the latest version of the code of conduct.
	 */
	public CodeOfConductDTO getCodeOfConduct(Person person) {
		InputStreamReader isReader;
		try {
			isReader = new InputStreamReader(
					new URL(queueProperties.getCodeOfConduct()).openConnection().getInputStream());
		} catch (IOException e) {
			logger.error("Invalid Code of Conduct URL {}", queueProperties.getCodeOfConduct(), e);
			return null;
		}
		String coc = "";
		try (BufferedReader reader = new BufferedReader(isReader)) {
			coc = reader.lines().collect(Collectors.joining("\n"));
		} catch (IOException e) {
			logger.error("Invalid Code of Conduct URL {}", queueProperties.getCodeOfConduct(), e);
			return null;
		} finally {
			coc = markdownService.markdownToHtml(coc);
		}
		return new CodeOfConductDTO(coc, lastTimeAccessed(person));
	}

	private LocalDateTime lastTimeAccessed(Person person) {
		return profileRepository.findProfileForPerson(person).getLastSeenCoc();
	}

}
