package jetbrains.buildServer.serverSide;

import jetbrains.buildServer.users.User;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Eugene Petrenko
 *         Created: 31.03.2010 16:21:11
 */
public class Rooms {
  private final AtomicInteger myRoomsCounter = new AtomicInteger(0);
  private final List<Room> myRooms = new CopyOnWriteArrayList<Room>();

  public Rooms() {
    //Create default room
    myRooms.add(new Room(1));
  }

  public void pingUser(User user) {
/*
    if (user == null) return;

    for (Room room : myRooms) {
      room.ping(user);
    }
*/
  }

  public int getRoomIdByUser(@Nullable User user) {
    return 666;
/*
    //killIdleAndMergeRooms();

    for (Room room : myRooms) {
      if (user == null || room.containsUser(user)) {
        return room.getRoomId();
      }
    }

    for (Room room : myRooms) {
      if (room.canInsertUser()) {
        room.addUser(user);
        return room.getRoomId();
      }
    }

    final Room room = new Room(myRoomsCounter.incrementAndGet());
    myRooms.add(room);
    room.addUser(user);
    return room.getRoomId();*/
  }

  private void killIdleAndMergeRooms() {
    for (Room room : myRooms) {
      room.killIdleMembers();
    }

    Set<Room> myObsoleteRooms = new HashSet<Room>();
    Set<Room> myStarvatingRooms = new HashSet<Room>();
    for (Room room : myRooms) {
      final int sz = room.getMembersCount();
      if (sz == 0) {
        myObsoleteRooms.add(room);
      }
      if (sz == 1) {
        myStarvatingRooms.add(room);
      }
    }

    //Remove rooms with nobody inside
    myRooms.removeAll(myObsoleteRooms);

    //Merge rooms where 1 client
    if (myStarvatingRooms.size() > 2) {
      Room h = null;
      for (Room room : myStarvatingRooms) {
        if (h == null) {
          h = room;
          continue;
        }

        if (h.canInsertUser()) {
          h.mergeWith(room);
          myRooms.remove(room);
        } else {
          h = room;
        }
      }
    }
  }

  @NotNull
  public Collection<Integer> getRoomsForEcho(Collection<Integer> skips) {
    return Collections.<Integer>emptySet();
/*
    List<Room> rooms = new ArrayList<Room>();
    rooms.addAll(myRooms);
    Collections.sort(rooms, new Comparator<Room>() {
      public int compare(Room o1, Room o2) {
        return o1.getLastMessageDate().compareTo(o2.getLastMessageDate());
      }
    });

    List<Integer> roomIds = new ArrayList<Integer>();
    for (Room room : rooms) {
      if (skips.contains(room.getRoomId())) continue;

      if (roomIds.size() > 3 + myRooms.size()/5) break;

      roomIds.add(room.getRoomId());
    }
    return roomIds;
*/
  }

  public Set<Integer> getAllRooms() {
    return Collections.singleton(getRoomIdByUser(null));
/*
    Set<Integer> list = new HashSet<Integer>();
    for (Room room : myRooms) {
      list.add(room.getRoomId());
    }
    return list;
*/
  }
}
