
import java.io.IOException;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonWriter;
import javax.json.stream.JsonGenerator;

@ServerEndpoint(value="/czat", configurator=WSKonfigurator.class)
public class CzatBean {
    private final static Map<Session, String> sesje;
    
    static {
        sesje = Collections.synchronizedMap(new HashMap<Session, String>());
    }
    
    @OnOpen
    public void otwarcieSesji(Session sesja, EndpointConfig konfiguracja) {
        String autor = (String)konfiguracja.getUserProperties().get("uzytkownik");
        sesje.put(sesja, autor);
        this.wyslijDoWszystkich(przygotujKomunikat("Dołączył użytkownik " + autor + "!", "SYSTEM"));
    }

    @OnClose
    public void koniecSesji(Session sesja) {
        String autor = sesje.get(sesja);
        sesje.remove(sesja);
        this.wyslijDoWszystkich(przygotujKomunikat("Użytkownik " + autor + " rozłączył się!", "SYSTEM"));
    }

    

    public String przygotujKomunikat(String wiadomosc, String autor) {
        try {
            StringWriter stringWriter = new StringWriter();
            JsonGenerator jsonGenerator = Json.createGenerator(stringWriter);
            String komunikatDoWyslania = String.format("%s > %s", autor, wiadomosc);
            jsonGenerator.writeStartObject().
                        write("autor", autor).
                        write("komunikat", komunikatDoWyslania).
                        writeEnd().
                        close();
            String result = stringWriter.getBuffer().toString();
            stringWriter.close();
            return result;
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
    
    @OnError
    public void blad(Throwable error) {
    }
    
    @OnMessage
    public void obsluzWiadomosc(String komunikat, Session sesja) {
        String autor = sesje.get(sesja);
        this.wyslijDoWszystkich(przygotujKomunikat(komunikat, autor));
    }

    private void wyslijDoWszystkich(String tekst) {
        synchronized(sesje) {
            for (Session sesja : sesje.keySet()) {
                try {
                    sesja.getBasicRemote().sendText(tekst);
                } catch (IOException ex) {
                    Logger.getLogger(CzatBean.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }
}
