package com.example.managedvms.gettingstartedjava.util;

import com.google.gcloud.datastore.Datastore;
import com.google.gcloud.datastore.DatastoreOptions;
import com.google.gcloud.datastore.Entity;
import com.google.gcloud.datastore.Key;
import com.google.gcloud.datastore.KeyFactory;

import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

/**
 * Since session variables are currently not available across Managed VM instances,
 * we extend HttpServlet to use datastore as a substitute for session variables.
 */
@SuppressWarnings("serial")
public abstract class DatastoreHttpServlet extends HttpServlet {

  private Datastore datastore;
  private Logger logger = Logger.getLogger(this.getClass().getName());
  private KeyFactory keyFactory;
  private Key key;
  private Entity.Builder entityBuilder;
  public void init() throws ServletException {
    datastore = DatastoreOptions.defaultInstance().service();
    keyFactory = datastore.newKeyFactory().kind("SessionVariables");
    key = keyFactory.newKey("bookshelf");
    Entity stateEntity = datastore.get(key);
    if (stateEntity == null) {
      entityBuilder = Entity.builder(key);
    } else {
      entityBuilder = Entity.builder(stateEntity);
    }
  }

  /**
   * Delete a value stored in the project's datastore.
   * @param varName
   */
  protected void deleteSessionVariable(String varName) {
    Entity stateEntity = datastore.get(key);
    Entity newEntity = Entity.builder(stateEntity).remove(varName).build();
    datastore.update(newEntity);
  }

  /**
   * Retrieve a value stored in the project's datastore.
   * do i still need? just list session variables at the beginning, otherwise, have multiple gets
   * @param varName
   * @return
   */
  protected String getSessionVariable(String varName) {
    Entity stateEntity = datastore.get(key);
    Set<String> names = stateEntity.names();
    Entity.Builder tempBuilder = Entity.builder(key);
    for (String name : names) {
      tempBuilder.set(name, stateEntity.getString(name));
      logger.log(Level.INFO, "previous session var " + name + " is " + stateEntity.getString(name));
    }
    String state = stateEntity.getString(varName);
    return state;
  }

  /**
   * stores the state value in the project's datastore.
   * @param varName TODO
   * @param varValue
   */
  protected void setSessionVariable(String varName, String varValue) {
    Entity stateEntity = datastore.get(key);
    if (stateEntity == null) {
      // does not exist yet
      logger.log(Level.INFO, "state entity was empty before set");
      stateEntity = Entity.builder(key).set(varName, varValue).build();
      datastore.put(stateEntity);
    } else {
      // add the old values
      Set<String> names = stateEntity.names();
      Entity.Builder tempBuilder = Entity.builder(key);
      for (String name : names) {
        tempBuilder.set(name, stateEntity.getString(name));
      }
      // add the new value
      logger.log(Level.INFO, "setting new session variable " + varName + " to " + varValue);
      datastore.put(tempBuilder.set(varName, varValue).build());
    }
  }

  protected Set<String> listSessionVariables() {
    Entity stateEntity = datastore.get(key);
    if (stateEntity == null) {
      logger.log(Level.INFO, "state entity was empty before get");
      stateEntity = Entity.builder(key).build();
      datastore.put(stateEntity);
    }
    return stateEntity.names();
  }
}

@@ -872,48 +872,8 @@
 ey;%0A
-  private Entity.Builder entityBuilder;%0A
   pu
@@ -915,16 +915,16 @@
 ption %7B%0A
+
     data
@@ -1092,197 +1092,8 @@
 %22);%0A
-    Entity stateEntity = datastore.get(key);%0A    if (stateEntity == null) %7B%0A      entityBuilder = Entity.builder(key);%0A    %7D else %7B%0A      entityBuilder = Entity.builder(stateEntity);%0A    %7D%0A
   %7D%0A
@@ -1701,304 +1701,8 @@
 y);%0A
-    Set%3CString%3E names = stateEntity.names();%0A    Entity.Builder tempBuilder = Entity.builder(key);%0A    for (String name : names) %7B%0A      tempBuilder.set(name, stateEntity.getString(name));%0A      logger.log(Level.INFO, %22previous session var %22 + name + %22 is %22 + stateEntity.getString(name));%0A    %7D%0A
     
@@ -2005,488 +2005,8 @@
 y);%0A
-    if (stateEntity == null) %7B%0A      // does not exist yet%0A      logger.log(Level.INFO, %22state entity was empty before set%22);%0A      stateEntity = Entity.builder(key).set(varName, varValue).build();%0A      datastore.put(stateEntity);%0A    %7D else %7B%0A      // add the old values%0A      Set%3CString%3E names = stateEntity.names();%0A      Entity.Builder tempBuilder = Entity.builder(key);%0A      for (String name : names) %7B%0A        tempBuilder.set(name, stateEntity.getString(name));%0A      %7D%0A  
     
@@ -2026,18 +2026,16 @@
 w value%0A
-  
     logg
@@ -2117,26 +2117,24 @@
 Value);%0A    
-  
 datastore.pu
@@ -2139,19 +2139,35 @@
 put(
-tempBuilder
+Entity.builder(stateEntity)
 .set
@@ -2196,22 +2196,16 @@
 ild());%0A
-    %7D%0A
   %7D%0A%0A  p

Simplify datastore calls