package com.backendless.persistence;


import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;


public final class JSONUpdateBuilder
{
	public static final String OPERATION_FIELD_NAME = "___operation";
	public static final String ARGS_FIELD_NAME = "args";
	
	public enum Operation
	{
		SET, INSERT, REPLACE, REMOVE, ARRAY_APPEND, ARRAY_INSERT;
	}
	
	
	private final HashMap<String, Object> jsonUpdate = new HashMap<>();
	
	private JSONUpdateBuilder(Operation op)
	{
		jsonUpdate.put(OPERATION_FIELD_NAME, op.name());
	}
	
	
	public static GeneralArgHolder SET()
	{
		return new JSONUpdateBuilder(Operation.SET).new GeneralArgHolder();
	}
	
	public static GeneralArgHolder INSERT()
	{
		return new JSONUpdateBuilder(Operation.INSERT).new GeneralArgHolder();
	}
	
	public static GeneralArgHolder REPLACE()
	{
		return new JSONUpdateBuilder(Operation.REPLACE).new GeneralArgHolder();
	}
	
	public static GeneralArgHolder ARRAY_APPEND()
	{
		return new JSONUpdateBuilder(Operation.ARRAY_APPEND).new GeneralArgHolder();
	}
	
	public static GeneralArgHolder ARRAY_INSERT()
	{
		return new JSONUpdateBuilder(Operation.ARRAY_INSERT).new GeneralArgHolder();
	}
	
	public static RemoveArgHolder REMOVE()
	{
		return new JSONUpdateBuilder(Operation.REMOVE).new RemoveArgHolder();
	}
	
	
	public final class GeneralArgHolder extends ArgHolder
	{
		private LinkedHashMap<String, Object> jsonUpdateArgs = new LinkedHashMap<>();
		
		private GeneralArgHolder()
		{
			JSONUpdateBuilder.this.jsonUpdate.put(ARGS_FIELD_NAME, jsonUpdateArgs);
		}
		
		public GeneralArgHolder addArgument(String jsonPath, Object value)
		{
			jsonUpdateArgs.put(jsonPath, value);
			return this;
		}
	}
	
	public final class RemoveArgHolder extends ArgHolder
	{
		private RemoveArgHolder()
		{
			JSONUpdateBuilder.this.jsonUpdate.put(ARGS_FIELD_NAME, jsonUpdateArgs);
		}
		
		private LinkedHashSet<String> jsonUpdateArgs = new LinkedHashSet<>();
		
		public RemoveArgHolder addArgument(String jsonPath)
		{
			jsonUpdateArgs.add(jsonPath);
			return this;
		}
	}
	
	public abstract class ArgHolder
	{
		private ArgHolder()
		{ }
		
		public HashMap<String, Object> create()
		{
			return JSONUpdateBuilder.this.jsonUpdate;
		}
	}
}

@@ -321,62 +321,352 @@
 %09SET
-, INSERT, REPLACE, REMOVE, ARRAY_APPEND, ARRAY_INSERT;
+(%22JSON_SET%22),%0A%09%09INSERT(%22JSON_INSERT%22),%0A%09%09REPLACE(%22JSON_REPLACE%22),%0A%09%09REMOVE(%22JSON_REMOVE%22),%0A%09%09ARRAY_APPEND(%22JSON_ARRAY_APPEND%22),%0A%09%09ARRAY_INSERT(%22JSON_ARRAY_INSERT%22);%0A%0A%09%09private String operationName;%0A%0A%09%09Operation(String operationName) %7B%0A%09%09%09this.operationName = operationName;%0A%09%09%7D%0A%0A%09%09public String getOperationName() %7B%0A%09%09%09return operationName;%0A%09%09%7D
 %0A%09%7D%0A
@@ -826,17 +826,29 @@
 AME, op.
-n
+getOperationN
 ame());%0A

Fix JsonUpdateBuilder operations