/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.actionbazaar.interfaces.socket;

import com.actionbazaar.application.BidService;
import com.actionbazaar.domain.Bid;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.enterprise.event.Observes;
import javax.enterprise.event.TransactionPhase;
import javax.inject.Inject;
import javax.websocket.EncodeException;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

/**
 * WebSocket Endpoint to broadcast events to clients and delete bid items 
 * identified by a bidId sent from a WebSocket client.
 * 
 */
@ServerEndpoint(value = "/bidnotifier",
    encoders = BidEventEncoderDecoder.class)
public class BidNotifierService {

    private static final Logger logger
            = Logger.getLogger(BidNotifierService.class.getName());

    @Inject
    BidService bidService;

    private static Session sessionRef = null;

    public BidNotifierService() {
        logger.info("constructor called");
    }

    @OnOpen
    public void init(Session session) {
        logger.info("WebsScket Endpoint initialized ");
        
        // Save session for later use with broadcast method,
        // Tyrus enables a session to continue to access its open peers 
        // even afer it has been closed.
        sessionRef = session;
        
        // Set the default timeout to 60s
        session.setMaxIdleTimeout(60 * 1000L);
    }

    /**
     * Receive WebSocketMessage with a String message type and delete the
     * accompanying bid
     *
     * @param session
     * @param bid
     */
    @OnMessage
    public void message(Session session, String message) {
        // Use the BidService to find and delete the given bid id
        Bid bid = bidService.getBid(Long.parseLong(message));
        if (bid != null) {
            logger.log(Level.INFO, "Deleting bid#: " + bid.getId());
            bidService.deleteBid(bid);
        } else {
            logger.log(Level.INFO, "Could not find bid# ${0}", message);
        }
    }

    //    /**
    //     * Receive WebSocketMessage with Bid as the Object type, constructed from 
    //     * the message via a decoder class specified on the Endpoint
    //     * 
    //     * @param session
    //     * @param bid 
    //     */
    //    @OnMessage
    //    public void message(Session session, Bid bid) {
    //        try {
    //            session.getBasicRemote().sendText(
    //                    String.format("You asked me to delete bid: %s@\\$%s for %s",
    //                            bid.getItem(),
    //                            bid.getAmount(),
    //                            bid.getBidder()));
    // Use the BidService to delete the specified BID
    //            bidService.deleteBid(bid);
    //        } catch (IOException ex) {
    //            Logger.getLogger(BidNotifierService.class.getName()).log(Level.SEVERE, null, ex);
    //        }
    //    }
    
    
    /**
     * Handle the CDI event when bid activity occurs, broadcast a
     * WebSocketMessage to all connected clients with details of bid activity.
     *
     * @param bidEvent
     */
    private void broadcastBidNotification(@Observes(during = TransactionPhase.AFTER_COMPLETION) BidEvent bidEvent) {
        logger.log(Level.INFO,
                "received event {0} {1}",
                new Object[]{
                    bidEvent.getType(),
                    bidEvent.getBid().toString()
                });

        if (sessionRef == null) {
            return;
        }

        for (Session session : sessionRef.getOpenSessions()) {
            try {
                session.getBasicRemote().sendObject(bidEvent);
            } catch (IOException | EncodeException ex) {
                logger.log(Level.SEVERE, null, ex);
            }
        }
    }
}
