package io.mewbase.example.shopping;

import io.mewbase.bson.BsonObject;
import io.mewbase.bson.BsonPath;
import io.mewbase.client.Client;
import io.mewbase.client.ClientOptions;
import io.mewbase.common.Delivery;
import io.mewbase.server.Server;
import io.mewbase.server.ServerOptions;


/**
 * Created by Nige on 17/05/17.
 */
public class FridgeExample {

    public static void main(String[] args) {
        try {
            new FridgeExample().exampleServer();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("Main complete");
    }

    /**
    Simple Fridge example
     */
    private void exampleServer() throws Exception {

        // Setup and start a server
        Server server = Server.newServer(new ServerOptions());
        server.start().get();
        server.createChannel("fridge.status").get();
        server.createBinder("fridges").get();

        // Register a projection that will respond to fridge door status events
        server.buildProjection("maintain_fridge_status")              // projection name
                .projecting("fridge.status")                                         // channel name
                .filteredBy(ev -> ev.getString("eventType").equals("doorStatus"))     // event filter
                .onto("fridges")                                                     // binder name
                .identifiedBy(ev -> ev.getString("fridgeID"))                   // document id selector; how to obtain the doc id from the event bson
                .as( (BsonObject fridge, Delivery del) ->  { // projection function
                        BsonObject evt = del.event();
                        long time =  del.timeStamp();
                        String doorStatus = evt.getString("status");
                        BsonPath.set(fridge, time, "timeStamp");
                        BsonPath.set(fridge, doorStatus, "door");
                        return fridge;
                } )
                .create();

        // run the client to exercise the server
        exampleClient();
        server.stop().get();
    }


    private void exampleClient() throws Exception {

        // Create a client
        Client client = Client.newClient(new ClientOptions());

        // Send some open close events for this fridge
        BsonObject event = new BsonObject().put("fridgeID", "f1").put("eventType", "doorStatus");

        // Open the door
        client.publish("fridge.status", event.copy().put("status", "open"));
        // wait for event to log and projection to fire
        Thread.sleep(100);

        // Now get the status
        BsonObject fridge = client.findByID("fridges", "f1").get();
        System.out.println("Fridge is: " + fridge);

        // Shut the door
        client.publish("fridge.status", event.copy().put("status", "shut"));
        Thread.sleep(100);

        // Now get the fridge details again
        fridge = client.findByID("fridges", "f1").get();
        System.out.println("Fridge is: " + fridge);

        client.close().get();
    }

}

@@ -286,16 +286,711 @@
 ;%0A%0A%0A/**%0A
+ * Fridge Example%0A *%0A * We assume that we have a number of Fridges (Refrigerators) that can raise IOT style events.%0A * Each time the Fridge produces an event we Publish the event via the mewbase client to the server.%0A * For each Fridge we maintain a Document in the 'fridges' Binder that reflects the current state%0A * of each of the fridges that are sending out events.%0A *%0A * Some extension that may be informative  ...%0A *%0A * 1) Introduce events from fridges with new Ids and check these also appear the Binder.%0A * 2) Introduce a new event that reflects the temperature of the fridge and integrate this into%0A * the current projection, or make a new projection to handle the new status event.%0A *%0A
  * Creat
@@ -1017,16 +1017,17 @@
 17.%0A */%0A
+%0A
 public c
@@ -1422,16 +1422,22 @@
         
+final 
 Server s
@@ -2347,61 +2347,13 @@
     
-BsonObject evt = del.event();%0A                       
+final
  lon
@@ -2403,16 +2403,22 @@
         
+final 
 String d
@@ -2433,11 +2433,19 @@
 s = 
-evt
+del.event()
 .get
@@ -2879,16 +2879,22 @@
         
+final 
 Client c
@@ -3332,24 +3332,30 @@
 bject fridge
+State1
  = client.fi
@@ -3412,36 +3412,42 @@
 println(%22Fridge 
-is: 
+State is :
 %22 + fridge);%0A%0A  
@@ -3432,32 +3432,38 @@
 e is :%22 + fridge
+State1
 );%0A%0A        // S
@@ -3614,15 +3614,13 @@
 dge 
-details
+state
  aga
@@ -3630,22 +3630,39 @@
         
-fridge
+BsonObject fridgeState2
  = clien
@@ -3735,12 +3735,18 @@
 dge 
-is: 
+State is :
 %22 + 
@@ -3751,16 +3751,22 @@
 + fridge
+State2
 );%0A%0A    

Comment and code tidy