package com.antonytrupe.server.tend;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import com.antonytrupe.server.games.GameEngine;
import com.antonytrupe.server.games.GameEngineException;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Text;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserServiceFactory;
@SuppressWarnings("serial")
public class API extends HttpServlet {
private enum Action {
LIST_BOARDS, RESET_COLLECTIONS,
// POPULATE,
CREATE_BOARD, GET_BOARD, RESET_SETTLEMENTS, JOIN_BOARD, QUEUE_SETTLEMENT, FINISH_TURN, COLLECT, TRADE;
}
private final GameEngine ge = new GameEngine(new String[] {
"/com/antonytrupe/tend/Resource.js",
"/com/antonytrupe/tend/ResourceGroup.js",
"/com/antonytrupe/tend/Point.js", "/com/antonytrupe/tend/Board.js",
"/com/antonytrupe/tend/Player.js",
"/com/antonytrupe/tend/Trade.js",
"/com/antonytrupe/tend/Settlement.js" });
public ScriptableObject createBoard() throws GameEngineException {
ScriptableObject board = ge.execute("new Board();");
ge.invoke(board, "grow", new Integer[] { 1, 0, 3, 1 });
// board.grow(1, 0, 3, 1);
ge.invoke(board, "grow", new Integer[] { 0, 1, 5, 3 });
// board.grow(0, 1, 5, 3);
ge.invoke(board, "grow", new Integer[] { 2, 4, 1, 1 });
// board.grow(2, 4, 1, 1); // return the board data
return board;
}
public ScriptableObject endTurn(ScriptableObject board)
throws GameEngineException {
ge.invoke(board, "endTurn", new String[] {});
save(board);
return board;
}
private ScriptableObject getBoard() throws GameEngineException {
HashMap<String, String> hashMap = ge.persistence.get("Board");
ScriptableObject board = createBoard();
update(board, hashMap.get("json"));
return board;
}
public ScriptableObject getBoard(long l) throws GameEngineException {
HashMap<String, Object> hashMap = ge.persistence.get("Board", l);
ScriptableObject board = createBoard();
update(board, (String) hashMap.get("json"));
return board;
}
public Long getId(ScriptableObject board) throws GameEngineException {
Object sd = ge.invoke(board, "getId");
if (sd == null
|| sd.getClass() == org.mozilla.javascript.Undefined.class)
return null;
else if (sd.getClass() == Long.class)
return (Long) sd;
else if (sd.getClass() == Integer.class) {
return Long.valueOf((Integer) sd);
} else {
return null;
}
}
private static String getUser(HttpServletRequest req) {
User currentUser = UserServiceFactory.getUserService().getCurrentUser();
// Principal userPrincipal = req.getUserPrincipal();
return currentUser != null ? currentUser.getEmail() : null;
// return userPrincipal != null ? userPrincipal.getName() : null;
}
protected ScriptableObject joinBoard(Long boardId, String userName)
throws GameEngineException {
ScriptableObject board;
if (boardId == null) {
board = createBoard();
} else {
board = getBoard(boardId);
}
return joinBoard(board, userName);
}
public ScriptableObject joinBoard(ScriptableObject board, String userName)
throws GameEngineException {
ge.invoke(board, "join", new String[] { userName });
save(board);
return board;
}
Scriptable queueSettlement(ScriptableObject board, String playerName,
String settlementPoint, String settlementName, String resources)
throws GameEngineException {
ge.invoke(board, "queueSettlement", new String[] { playerName,
settlementPoint, settlementName, resources });
save(board);
return board;
}
public ScriptableObject save(ScriptableObject board)
throws GameEngineException {
Long id = getId(board);
Entity result;
if (id == null) {
result = ge.persistence.save("Board");
id = result.getKey().getId();
setId(board, result.getKey().getId());
}
String json = (String) ge.invoke(board, "stringify");
result = ge.persistence.save("Board", id, "json", json);
// load(board, json);
return board;
}
public void setId(ScriptableObject board, long id)
throws GameEngineException {
ge.invoke(board, "setId", new Object[] { id });
}
String stringify(ScriptableObject board) throws GameEngineException {
String json = (String) ge.invoke(board, "stringify");
return json;
}
public void update(ScriptableObject board, String json)
throws GameEngineException {
ge.invoke(board, "update", new String[] { "{\"board\":" + json + "}" });
}
@Override
public void doGet(final HttpServletRequest request,
final HttpServletResponse response) {
response.setContentType("application/json");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
response.setHeader("Access-Control-Allow-Credentials", "true");
@SuppressWarnings("unchecked")
final Map<String, String[]> parameters = request.getParameterMap();
final String user = getUser(request);
try {
final String result = process(parameters, user, response);
response.getWriter().println("{ ");
response.getWriter().println(
"\"user\":\"" + (user != null ? user : "") + "\",");
response.getWriter().println(result);
response.getWriter().println("}");
// System.out.println(result);
} catch (IOException e) {
e.printStackTrace();
} catch (GameEngineException e) {
e.printStackTrace();
}
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) {
doGet(request, response);
}
private ScriptableObject endTurn(ScriptableObject board, String user)
throws GameEngineException {
ge.invoke(board, "endTurn", new String[] {});
save(board);
return board;
}
private Long getBoardId(Map<String, String[]> parameters) {
String s = getParameter("id", parameters);
Long parseLong = null;
if (s != null && s != "" && !s.equals("null")) {
parseLong = Long.parseLong(s);
}
return parseLong;
}
private String getParameter(String name, Map<String, String[]> parameters) {
String s = null;
if (parameters.get(name) != null && parameters.get(name).length > 0) {
s = parameters.get(name)[0];
s = s.replace("!", "");
}
return s;
}
private String process(final Map<String, String[]> parameters,
final String user, final HttpServletResponse response)
throws GameEngineException {
final String[] strings = parameters.get("action");
Action action = Action.GET_BOARD;
if (strings != null && strings.length > 0) {
final String string = strings[0];
action = Action.valueOf(string);
}
String json = "";
switch (action) {
case GET_BOARD: {
final Long boardId = getBoardId(parameters);
final ScriptableObject board;
if (boardId != null) {
board = getBoard(boardId);
} else {
board = getBoard();
}
json += "\"board\":";
json += stringify(board);
break;
}
case JOIN_BOARD:
if (user == null || user == "") {
// /login.html?return_to=hex%252Fapi%253Faction%253DJOIN_BOARD
final Long boardId = getBoardId(parameters);
try {
response.sendRedirect("/login.html?return_to=tend%252Fapi%253Faction%253DJOIN_BOARD%2526id%253D"
+ boardId);
return null;
} catch (IOException e1) {
e1.printStackTrace();
}
}
final Long boardId = getBoardId(parameters);
joinBoard(boardId, user);
try {
// Long id = (Long) board.get("id");
response.sendRedirect("/tend/#!" + boardId);
return null;
} catch (IOException e) {
e.printStackTrace();
}
break;
case COLLECT:
break;
case CREATE_BOARD:
break;
case FINISH_TURN: {
ScriptableObject board = getBoard(getBoardId(parameters));
endTurn(board, user);
json += "\"board\":";
json += stringify(board);
}
break;
case LIST_BOARDS:
json = "\"boards\":[";
HashMap<Object, HashMap<String, Object>> boards = ge.persistence
.getAll("Board");
for (Entry<Object, HashMap<String, Object>> board : boards
.entrySet()) {
String ad = ((Text) board.getValue().get("json")).getValue();
json += ad + ",";
}
json = json.substring(0, json.length() - 1);
json += "]";
break;
case RESET_COLLECTIONS:
break;
case RESET_SETTLEMENTS:
break;
case TRADE:
break;
case QUEUE_SETTLEMENT:
ScriptableObject board = getBoard(getBoardId(parameters));
String settlementPoint = getParameter("settlementPoint", parameters);
String settlementName = getParameter("settlementName", parameters);
String resources = getParameter("resources", parameters);
queueSettlement(board, user, settlementPoint, settlementName,
resources);
json += "\"board\":";
json += stringify(board);
break;
}
return json;
}
}