package com.r11.tools.service;

import com.r11.tools.mappers.MockedMessageMapper;
import com.r11.tools.model.MockedMessage;
import com.r11.tools.model.MockedMessageDto;
import com.r11.tools.repository.MockedResponseRepository;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.Optional;
import java.util.UUID;

/**
 * Service for {@link com.r11.tools.controller.MockController} and {@link com.r11.tools.controller.MockController}
 * Allows for performing CRUD operations on {@link MockedMessageDto}
 * @author Rafał Żukowicz
 * @author Gabriel Modzelewski
 * @author Mikołaj Widła
 */
@Service
@AllArgsConstructor
public class KlausServiceImpl implements KlausService {
    private final MockedMessageMapper mockedMessageMapper;
    private final Logger log = LogManager.getRootLogger();
    private final MockedResponseRepository mockedResponseRepository;


    /**
     * Returns all messages of given key-uuid
     * @param clientUUID the key-uuid of given set of messages
     * @return List of {@link MockedMessageDto}
     */
    @Override
    public Optional<MockedMessageDto> getMockedMessageByClientUUID(UUID clientUUID){
        Optional<MockedMessage> mockedMessageOptional = mockedResponseRepository.findAllByClientUUID(clientUUID);
        log.info("Message for UUID: "+clientUUID+" has been fetched from DB.");
        return mockedMessageMapper.optionalMockedMessageToOptionalMockedMessageDTO(mockedMessageOptional);
    }

    /**
     * Returns {@link MockedMessageDto} of given id and key-uuid. If message doesn't then empty message is returned
     * @param clientUUID the key-uuid of given set of messages
     * @return {@link MockedMessageDto} object
     */
    @SneakyThrows
    @Override
    public MockedMessageDto getMockedResponse(UUID clientUUID){
        Optional<MockedMessage> optionalMockedMessage = mockedResponseRepository.findById(clientUUID);
        MockedMessageDto mockedMessageDto = MockedMessageDto.builder()
                .clientUUID(clientUUID)
                .build();
        if (optionalMockedMessage.isPresent()) {
            mockedMessageDto = mockedMessageMapper.mockedMessageToMockedMessageDto(optionalMockedMessage.get());
            //log.info(mockedMessageDto.toString().replaceAll("\"", "\\\\\""));
            return mockedMessageDto;
        }
        //log.info(mockedMessageDto.toString().replaceAll("\"", "\\\\\""));
        return mockedMessageDto;
    }

    /**
     * Allows to modify mocked message. If message of given id and key-uuid doesn't exist a new entry is created
     * @param mockedMessageDto message to be saved
     * @return Confirmation and status 200 OK
     */
    @SneakyThrows
    @Override
    public ResponseEntity<String> setMockedResponse(MockedMessageDto mockedMessageDto) {
        mockedResponseRepository.save(mockedMessageMapper.mockedMessageDtoToMockedMessage(mockedMessageDto));
        //log.info(mockedMessageDto.toString().replaceAll("\"", "\\\\\""));
        return new ResponseEntity<>("MockedResponse has been setup successfully!", new HttpHeaders(),
                HttpStatus.ACCEPTED);
    }

}
