package org.msf.records.user.testing;

import com.google.common.collect.Sets;

import org.msf.records.model.User;
import org.msf.records.user.UserStore;

import java.util.Set;

/**
 * A fake user store for testing out user flows before we have server integration.
 */
public class FakeUserStore extends UserStore {

    private Set<User> mServerKnownUsers;
    private Set<User> mLocalKnownUsers;
    private int mNextId;

    public FakeUserStore() {
        User akalachman = User.create("akalachman", "Adam Kalachman");
        User cpritchard = User.create("cpritchard", "Corinne Pritchard");
        User dan = User.create("dan", "Dan Cunningham");
        User danielsjulio = User.create("danielsjulio", "Daniel Julio");
        User dxchen = User.create("dxchen", "David Chen");
        User gilsjulio = User.create("gilsjulio", "Gil Julio");
        User gansha = User.create("gansha", "Ganesh Shankar");
        User isabella = User.create("isabella", "Isabella Pighi");
        User ivangayton = User.create("ivangayton", "Ivan Gayton");
        User jonskeet = User.create("jonskeet", "Jon Skeet");
        User kenk = User.create("kenk", "Ken Krieger");
        User koen = User.create("koen", "Koen Vendrik");
        User kpy = User.create("kpy", "Ka-Ping Yee");
        User madhul = User.create("madhul", "Madhuwati Lagu");
        User nfortescue = User.create("nfortescue", "Nick Fortescue");
        User peteg = User.create("peteg", "Pete Gillin");
        User pim = User.create("pim", "Pim de Witte");
        User sanderlatour = User.create("sanderlatour", "Sander Latour");
        User scrossan = User.create("scrossan", "Steve Crossan");

        Set<User> allKnownUsers =
                Sets.newHashSet(akalachman, cpritchard, dan, danielsjulio, dxchen, gilsjulio,
                        gansha, isabella, ivangayton, jonskeet, kenk, koen, kpy, madhul,
                        nfortescue, peteg, pim, sanderlatour, scrossan);

        // Server doesn't have Nick.
        mServerKnownUsers = Sets.newHashSet(allKnownUsers);
        mServerKnownUsers.remove(nfortescue);

        // Local doesn't have Ping.
        mLocalKnownUsers = Sets.newHashSet(allKnownUsers);
        mLocalKnownUsers.remove(kpy);
    }

    @Override
    public Set<User> loadKnownUsers() {
        return Sets.newHashSet(mLocalKnownUsers);
    }

    @Override
    public Set<User> syncKnownUsers() {
        mLocalKnownUsers = Sets.newHashSet(mServerKnownUsers);
        return Sets.newHashSet(mLocalKnownUsers);
    }

    // TODO(dxchen): Users presumably will have a server-side user ID. Should we have a data type
    // for a new user that excludes the user ID?
    @Override
    public User addUser(User user) {
        if (mLocalKnownUsers.contains(user)) {
            throw new RuntimeException("Local user already exists.");
        }

        if (mServerKnownUsers.contains(user)) {
            throw new RuntimeException("Server user already exists.");
        }

        mServerKnownUsers.add(user);
        mLocalKnownUsers.add(user);

        return user;
    }

    @Override
    public User deleteUser(User user) {
        if (!mLocalKnownUsers.contains(user)) {
            throw new RuntimeException("No local user with that ID.");
        }

        if (!mServerKnownUsers.contains(user)) {
            throw new RuntimeException("No server user with that ID.");
        }

        mServerKnownUsers.remove(user);
        mLocalKnownUsers.remove(user);

        return user;
    }
}

@@ -1704,20 +1704,16 @@
         
-    
 Sets.new
@@ -1798,24 +1798,16 @@
         
-        
 gansha, 
@@ -1863,24 +1863,16 @@
 madhul,%0A
-        
         
@@ -2205,16 +2205,38 @@
 ve(kpy);
+%0A%0A        mNextId = 1;
 %0A    %7D%0A%0A
@@ -2968,32 +2968,211 @@
 .%22);%0A        %7D%0A%0A
+        // Fake out an RPC to the server asking it to create a new user.%0A        String id = %22user%22 + (mNextId++);%0A        User userWithId = User.create(id, user.getFullName());%0A%0A
         mServerK
@@ -3185,24 +3185,30 @@
 ers.add(user
+WithId
 );%0A        m
@@ -3227,24 +3227,30 @@
 ers.add(user
+WithId
 );%0A%0A        
@@ -3252,32 +3252,38 @@
      return user
+WithId
 ;%0A    %7D%0A%0A    @Ov

Revert to generating IDs from mNextId.