
import java.io.IOException;
import java.io.Serializable;
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.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Singleton;
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)
@Dependent
public class CzatBean {
    
    @Inject
    private SesjeBean sesjeBean;
    
    public CzatBean() {
        
    }
    @PostConstruct
    public void init() {
        System.out.println("This: " + this);
    }
    
    @OnOpen
    public void otwarcieSesji(Session sesja, EndpointConfig konfiguracja) {
        String autor = (String)konfiguracja.getUserProperties().get("uzytkownik");
        getSesjeBean().getSesje().put(sesja, autor);
        this.wyslijDoWszystkich(przygotujKomunikat("Dołączył użytkownik " + autor + "!", "SYSTEM"));
    }

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

    @OnError
    public void blad(Throwable error) {
    }

    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 "";
    }
    
    @OnMessage
    public void obsluzWiadomosc(String komunikat, Session sesja) {
        String autor = getSesjeBean().getSesje().get(sesja);
        this.wyslijDoWszystkich(przygotujKomunikat(komunikat, autor));
    }

    private void wyslijDoWszystkich(String tekst) {
        Map<Session, String> sesje = getSesjeBean().getSesje();
        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);
                }
            }
        }
    }

    public boolean sprawdzDostepnosc(String login) {
        Map<Session, String> sesje = getSesjeBean().getSesje();
       
        synchronized(sesje) {
            for (String autor : sesje.values())
                if (autor.equals(login))
                    return false;
        }
        return true;
    }

    /**
     * @return the sesjeBean
     */
    public SesjeBean getSesjeBean() {
        
        return sesjeBean;
    }

    /**
     * @param sesjeBean the sesjeBean to set
     */
    public void setSesjeBean(SesjeBean sesjeBean) {
        this.sesjeBean = sesjeBean;
    }
}
