package com.beowulfe.hap.impl.json;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.json.JsonValue;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.beowulfe.hap.characteristics.Characteristic;
import com.beowulfe.hap.characteristics.EventableCharacteristic;
import com.beowulfe.hap.impl.HomekitRegistry;
import com.beowulfe.hap.impl.connections.SubscriptionManager;
import com.beowulfe.hap.impl.http.HomekitClientConnection;
import com.beowulfe.hap.impl.http.HttpRequest;
import com.beowulfe.hap.impl.http.HttpResponse;
import com.beowulfe.hap.impl.responses.NotFoundResponse;

public class CharacteristicsController {
	
	Logger logger = LoggerFactory.getLogger(CharacteristicsController.class);

	private final HomekitRegistry registry;
	private final SubscriptionManager subscriptions;
	
	public CharacteristicsController(HomekitRegistry registry, SubscriptionManager subscriptions) {
		this.registry = registry;
		this.subscriptions = subscriptions;
	}
	
	public HttpResponse get(HttpRequest request) throws Exception {
		String uri = request.getUri();
		String query = uri.substring("/characteristics?q=".length()+1);
		String[] parts = query.split("\\.");
		if (parts.length != 2) {
			logger.error("Unexpected characteristics request: "+uri);
			return new NotFoundResponse();
		}
		int aid = Integer.parseInt(parts[0]);
		int iid = Integer.parseInt(parts[1]);
		JsonObjectBuilder characteristic = Json.createObjectBuilder();
		registry.getCharacteristics(aid).get(iid).supplyValue(characteristic);
		
		JsonObject result = Json.createObjectBuilder()
			.add("characteristics", Json.createArrayBuilder()
					.add(characteristic
							.add("aid", aid)
							.add("iid", iid)
							.build()
					).build()
		).build();
		try(ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
			Json.createWriter(baos).write(result);
			return new HapJsonResponse(baos.toByteArray());
		}
	}

	public HttpResponse put(HttpRequest request, HomekitClientConnection connection) throws Exception {
		try(ByteArrayInputStream bais = new ByteArrayInputStream(request.getBody())) {
			JsonArray jsonCharacteristics = Json.createReader(bais)
					.readObject().getJsonArray("characteristics");
			for (JsonValue value: jsonCharacteristics) {
				JsonObject jsonCharacteristic = (JsonObject) value;
				int aid = jsonCharacteristic.getInt("aid");
				int iid = jsonCharacteristic.getInt("iid");
				Characteristic characteristic = registry.getCharacteristics(aid).get(iid);
				
				if (jsonCharacteristic.containsKey("value")) {
					characteristic.setValue(jsonCharacteristic.get("value"));
				}
				if (jsonCharacteristic.containsKey("ev") && characteristic instanceof EventableCharacteristic) {
					if (jsonCharacteristic.getBoolean("ev")) {
						subscriptions.addSubscription(aid, iid, (EventableCharacteristic) characteristic, connection);
					} else {
						subscriptions.removeSubscription((EventableCharacteristic) characteristic, connection);
					}
				}
			}
		}
		return new HapJsonNoContentResponse();
	}

}

@@ -159,16 +159,52 @@
 nArray;%0A
+import javax.json.JsonArrayBuilder;%0A
 import j
@@ -1169,17 +1169,16 @@
 ons;%0A%09%7D%0A
-%09
 %0A%09public
@@ -1268,16 +1268,88 @@
 tUri();%0A
+%09%09// Characteristics are requested with /characteristics?id=1.1,2.1,3.1%0A
 %09%09String
@@ -1389,17 +1389,18 @@
 ristics?
-q
+id
 =%22.lengt
@@ -1406,10 +1406,8 @@
 th()
-+1
 );%0A%09
@@ -1420,21 +1420,144 @@
 g%5B%5D 
-parts = query
+ids = query.split(%22,%22);%0A%09%09JsonArrayBuilder characteristics = Json.createArrayBuilder();%0A%09%09for (String id : ids) %7B%0A%09%09%09String%5B%5D parts = id
 .spl
@@ -1569,16 +1569,17 @@
 %5C.%22);%0A%09%09
+%09
 if (part
@@ -1595,16 +1595,17 @@
 != 2) %7B%0A
+%09
 %09%09%09logge
@@ -1654,9 +1654,11 @@
 t: %22
-+
+ + 
 uri)
@@ -1658,24 +1658,25 @@
  + uri);%0A%09%09%09
+%09
 return new N
@@ -1696,18 +1696,20 @@
 se();%0A%09%09
+%09
 %7D%0A
+%09
 %09%09int ai
@@ -1742,16 +1742,17 @@
 %5B0%5D);%0A%09%09
+%09
 int iid 
@@ -1781,16 +1781,17 @@
 ts%5B1%5D);%0A
+%09
 %09%09JsonOb
@@ -1847,16 +1847,17 @@
 lder();%0A
+%09
 %09%09regist
@@ -1925,118 +1925,27 @@
 c);%0A
-%09%09
 %0A%09%09
-JsonObject result = Json.createObjectBuilder()%0A%09%09%09.add(%22characteristics%22, Json.createArrayBuilder()%0A%09%09%09%09%09
+%09characteristics
 .add
@@ -1959,24 +1959,16 @@
 teristic
-%0A%09%09%09%09%09%09%09
 .add(%22ai
@@ -1975,24 +1975,16 @@
 d%22, aid)
-%0A%09%09%09%09%09%09%09
 .add(%22ii
@@ -1995,52 +1995,22 @@
 iid)
-%0A%09%09%09%09%09%09%09.build()%0A%09%09%09%09%09).build()%0A%09%09).build();
+.build());%0A%09%09%7D
 %0A%09%09t
@@ -2109,14 +2109,90 @@
 ite(
-result
+Json.createObjectBuilder().add(%22characteristics%22, characteristics.build()).build()
 );%0A%09

Fix GET /characteristics