package net.cobem.grizzly.habbohotel.sessions;

import net.cobem.grizzly.Grizzly;
import net.cobem.grizzly.communication.EventResponse;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.DefaultChannelGroup;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class SessionHandler {
    private Map<Channel, Session> SessionList = new HashMap<Channel, Session>();

    public Session create(Channel Channel) {
        Session mSession = new Session(Channel, (SessionList.size() + 1));

        Channel.setAttachment(mSession);

        SessionList.put(Channel, mSession);

        if (Grizzly.getConfig().get("grizzly.connection.log").equals("1")) {
            Grizzly.write("Started communication with " + mSession.ip() + " [" + mSession.id() + "]");
        }
        return mSession;
    }

    public void remove(Channel mChannel) {
        SessionList.remove(mChannel);
    }

    public void kill(Session mSession) {
        try {
            mSession.getHabbo().refreshMessenger(false);
        } catch (Exception e) {
            System.gc();
            return;
        }

        if (mSession.getActor() != null) {
            mSession.getActor().GoalRoom = 0;

            mSession.leaveRoom(true);
        }

        SessionList.remove(mSession.getChannel());

        Grizzly.getStorage().execute("UPDATE users SET online = '0' WHERE id = '" + mSession.getHabbo().getID() + "'");

        //if (Grizzly.getConfig().get("grizzly.connection.log").equals("1"))
        {
            Grizzly.write("Killed communication with " + mSession.ip() + " [" + mSession.id() + "]");
        }

        mSession.getChannel().disconnect();

        System.gc();
    }

    public Session get(Channel Channel) {
        if (SessionList.containsKey(Channel)) {
            return SessionList.get(Channel);
        } else {
            Grizzly.write("For some reason Grizzly tried to retrieve an empty session!!");
            return null;
        }
    }

    public Session getByID(int ID) {
        this.cleanSessions();

        for (Session mSession : this.SessionList.values()) {
            try {
                if (mSession.getHabbo().getID() == ID) {
                    return mSession;
                }
            } catch (NullPointerException ex) {
                continue;
            }
        }

        return null;
    }

    public Session getByName(String Name) {
        this.cleanSessions();

        for (Session mSession : this.SessionList.values()) {
            if (mSession.getHabbo().getUsername().equalsIgnoreCase(Name)) {
                return mSession;
            }
        }

        return null;
    }

    private boolean cleanSessions() {

        List<Session> RemoveList = new ArrayList<>();

        for (Session mSession : this.SessionList.values()) {
            if (!mSession.getChannel().isOpen() || !mSession.getChannel().isWritable()) {
                RemoveList.add(mSession);
            }
        }

        for (Session Removed : RemoveList) {
            SessionList.remove(Removed);
        }

        return true;
    }

    public Map<Channel, Session> getSessions() {
        return SessionList;
    }

    public void sendHotelMessage(EventResponse Message) {
        ChannelGroup Group = new DefaultChannelGroup();

        Group.addAll(SessionList.keySet());

        Group.write(Message);
    }
}
