// Path: src/main/java/io/hosuaby/restful/domain/TeapotMessage.java
// public class TeapotMessage {
// 
//     /** Client id */
//     private String clientId;
// 
//     /** Message payload */
//     private String payload;
// 
//     public TeapotMessage() {
//         super();
//     }
// 
//     public TeapotMessage(String clientId, String payload) {
//         super();
//         this.clientId = clientId;
//         this.payload = payload;
//     }
// 
//     public String getClientId() {
//         return clientId;
//     }
// 
//     public void setClientId(String clientId) {
//         this.clientId = clientId;
//     }
// 
//     public String getPayload() {
//         return payload;
//     }
// 
//     public void setPayload(String payload) {
//         this.payload = payload;
//     }
// 
// }
// 
// Path: src/main/java/io/hosuaby/restful/repositories/WebSocketSessionRepository.java
// public class WebSocketSessionRepository {
// 
//     /**
//      * Sessions store.
//      */
//     private Map<String, WebSocketSession> sessions;
// 
//     /**
//      * Creates an instance backed by a {@link ConcurrentHashMap}
//      */
//     public WebSocketSessionRepository() {
//         sessions = new HashMap<>();     // not thread safe HashMap
//     }
// 
//     /**
//      * Saves the session. If session was already registered method does nothing.
//      *
//      * @param session    web socket session
//      */
//     public void save(WebSocketSession session) {
//         sessions.put(session.getId(), session);
//     }
// 
//     /**
//      * Returns all websocket sessions from this repository.
//      *
//      * @return collection of websocket sessions
//      */
//     public Collection<WebSocketSession> getSessions() {
//         return sessions.values();
//     }
// 
//     /**
//      * Returns the session by it's id.
//      *
//      * @param id    session id
//      *
//      * @return websocket session, if no session was found returns null.
//      */
//     public WebSocketSession getSession(String id) {
//         return sessions.get(id);
//     }
// 
//     /**
//      * Deletes the session with defined id. If not session with this id was
//      * defined, method does nothing.
//      *
//      * @param id    session id
//      */
//     public void delete(String id) {
//         sessions.remove(id);
//     }
// 
//     /**
//      * Deletes the session. If defined session was not found, method does
//      * nothing.
//      *
//      * @param session    websocket session
//      */
//     public void delete(WebSocketSession session) {
//         sessions.remove(session.getId());
//     }
// 
// }
// 
// Path: src/main/java/io/hosuaby/restful/services/exceptions/teapots/TeapotInternalErrorException.java
// public class TeapotInternalErrorException extends Exception {
// 
//     /**
//      * Serial ID.
//      */
//     private static final long serialVersionUID = 5083886954829581207L;
// 
//     /**
//      * Constructor from error message.
//      *
//      * @param error    error message
//      */
//     public TeapotInternalErrorException(String error) {
//         super(error);
//     }
// }
// 
// Path: src/main/java/io/hosuaby/restful/services/exceptions/teapots/TeapotNotConnectedException.java
// public class TeapotNotConnectedException extends Exception {
// 
//     /**
//      * When teapot with defined id not exists.
//      */
//     private static final String ERR_TEAPOT_NOT_CONNECTED = "Teapot with id \"%s\" not connected to server";
// 
//     /**
//      * Serial ID.
//      */
//     private static final long serialVersionUID = 3484631448010563705L;
// 
//     /**
//      * Constructor from teapot id.
//      *
//      * @param teapotId    teapot id
//      */
//     public TeapotNotConnectedException(String teapotId) {
//         super(String.format(ERR_TEAPOT_NOT_CONNECTED, teapotId));
//     }
// 
// }


import io.hosuaby.restful.domain.TeapotMessage;
import io.hosuaby.restful.repositories.WebSocketSessionRepository;
import io.hosuaby.restful.services.exceptions.teapots.TeapotInternalErrorException;
import io.hosuaby.restful.services.exceptions.teapots.TeapotNotConnectedException;
import java.io.IOException;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.async.DeferredResult;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import com.fasterxml.jackson.databind.ObjectMapper;
package io.hosuaby.restful.services;






/**
 * Implementation of the {@link TeapotCommandService}.
 */
@Service
// TODO: implement appropriate thread synchronization
public class TeapotCommandServiceImpl implements TeapotCommandService {

    /**
     * Pattern for request id. Id must start with sequence "req-".
     */
    private static final Pattern REQUEST_ID_PATTERN = Pattern.compile("^req-.*");

    /** Repository for websocket sessions of teapots */
    @Autowired
    @Qualifier("teapotSessionsRepository")
// Path: src/main/java/io/hosuaby/restful/domain/TeapotMessage.java
// public class TeapotMessage {
// 
//     /** Client id */
//     private String clientId;
// 
//     /** Message payload */
//     private String payload;
// 
//     public TeapotMessage() {
//         super();
//     }
// 
//     public TeapotMessage(String clientId, String payload) {
//         super();
//         this.clientId = clientId;
//         this.payload = payload;
//     }
// 
//     public String getClientId() {
//         return clientId;
//     }
// 
//     public void setClientId(String clientId) {
//         this.clientId = clientId;
//     }
// 
//     public String getPayload() {
//         return payload;
//     }
// 
//     public void setPayload(String payload) {
//         this.payload = payload;
//     }
// 
// }
// 
// Path: src/main/java/io/hosuaby/restful/repositories/WebSocketSessionRepository.java
// public class WebSocketSessionRepository {
// 
//     /**
//      * Sessions store.
//      */
//     private Map<String, WebSocketSession> sessions;
// 
//     /**
//      * Creates an instance backed by a {@link ConcurrentHashMap}
//      */
//     public WebSocketSessionRepository() {
//         sessions = new HashMap<>();     // not thread safe HashMap
//     }
// 
//     /**
//      * Saves the session. If session was already registered method does nothing.
//      *
//      * @param session    web socket session
//      */
//     public void save(WebSocketSession session) {
//         sessions.put(session.getId(), session);
//     }
// 
//     /**
//      * Returns all websocket sessions from this repository.
//      *
//      * @return collection of websocket sessions
//      */
//     public Collection<WebSocketSession> getSessions() {
//         return sessions.values();
//     }
// 
//     /**
//      * Returns the session by it's id.
//      *
//      * @param id    session id
//      *
//      * @return websocket session, if no session was found returns null.
//      */
//     public WebSocketSession getSession(String id) {
//         return sessions.get(id);
//     }
// 
//     /**
//      * Deletes the session with defined id. If not session with this id was
//      * defined, method does nothing.
//      *
//      * @param id    session id
//      */
//     public void delete(String id) {
//         sessions.remove(id);
//     }
// 
//     /**
//      * Deletes the session. If defined session was not found, method does
//      * nothing.
//      *
//      * @param session    websocket session
//      */
//     public void delete(WebSocketSession session) {
//         sessions.remove(session.getId());
//     }
// 
// }
// 
// Path: src/main/java/io/hosuaby/restful/services/exceptions/teapots/TeapotInternalErrorException.java
// public class TeapotInternalErrorException extends Exception {
// 
//     /**
//      * Serial ID.
//      */
//     private static final long serialVersionUID = 5083886954829581207L;
// 
//     /**
//      * Constructor from error message.
//      *
//      * @param error    error message
//      */
//     public TeapotInternalErrorException(String error) {
//         super(error);
//     }
// }
// 
// Path: src/main/java/io/hosuaby/restful/services/exceptions/teapots/TeapotNotConnectedException.java
// public class TeapotNotConnectedException extends Exception {
// 
//     /**
//      * When teapot with defined id not exists.
//      */
//     private static final String ERR_TEAPOT_NOT_CONNECTED = "Teapot with id \"%s\" not connected to server";
// 
//     /**
//      * Serial ID.
//      */
//     private static final long serialVersionUID = 3484631448010563705L;
// 
//     /**
//      * Constructor from teapot id.
//      *
//      * @param teapotId    teapot id
//      */
//     public TeapotNotConnectedException(String teapotId) {
//         super(String.format(ERR_TEAPOT_NOT_CONNECTED, teapotId));
//     }
// 
// }


// Path: src/main/java/io/hosuaby/restful/services/TeapotCommandServiceImpl.java
import io.hosuaby.restful.domain.TeapotMessage;
import io.hosuaby.restful.repositories.WebSocketSessionRepository;
import io.hosuaby.restful.services.exceptions.teapots.TeapotInternalErrorException;
import io.hosuaby.restful.services.exceptions.teapots.TeapotNotConnectedException;
import java.io.IOException;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.async.DeferredResult;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import com.fasterxml.jackson.databind.ObjectMapper;

package io.hosuaby.restful.services;






/**
 * Implementation of the {@link TeapotCommandService}.
 */
@Service
// TODO: implement appropriate thread synchronization
public class TeapotCommandServiceImpl implements TeapotCommandService {

    /**
     * Pattern for request id. Id must start with sequence "req-".
     */
    private static final Pattern REQUEST_ID_PATTERN = Pattern.compile("^req-.*");

    /** Repository for websocket sessions of teapots */
    @Autowired
    @Qualifier("teapotSessionsRepository")
    private WebSocketSessionRepository sessionRepository;