package org.iotivity.bridge.homeserver.handler.server;

import android.util.Log;

import org.iotivity.OCCoreRes;
import org.iotivity.OCInterfaceMask;
import org.iotivity.OCRequest;
import org.iotivity.OCRequestHandler;
import org.iotivity.OCStatus;
import org.iotivity.OCUuid;
import org.iotivity.OCUuidUtil;
import org.iotivity.bridge.homeserver.BridgeService;
import org.iotivity.bridge.homeserver.model.Light;
import org.iotivity.bridge.homeserver.model.OCFDevice;
import org.iotivity.oc.OcCborEncoder;
import org.iotivity.oc.OcUtils;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Properties;

public class GetRequestHandler implements OCRequestHandler {

    private static final String TAG = GetRequestHandler.class.getSimpleName();

    private BridgeService service;
    private OCFDevice device;

    public GetRequestHandler(BridgeService service, OCFDevice device) {
        this.service = service;
        this.device = device;
    }

    @Override
    public void handler(OCRequest request, int interfaces) {
        Log.d(TAG, "inside Get Request Handler");

        long device_index = request.getResource().getDevice();
        OCUuid uuid = OCCoreRes.getDeviceId(device_index);
        String device_uuid = OCUuidUtil.uuidToString(uuid);
        String resource_uri = request.getResource().getUri();

        service.msg("Get "+resource_uri+" of "+device_uuid+"("+device.getDeviceName()+") Request Received.");
        String properies = service.doGetLightControlResource(device_index, device_uuid, resource_uri);
        device.addProperties(resource_uri, properies);

        OcCborEncoder root = OcCborEncoder.createOcCborEncoder(OcCborEncoder.EncoderType.ROOT);
        switch (interfaces) {
            case OCInterfaceMask.BASELINE: {
                root.processBaselineInterface(request.getResource());
                break;
            }
            case OCInterfaceMask.R:
            case OCInterfaceMask.RW:
            case OCInterfaceMask.S:
            case OCInterfaceMask.A:

                // return current value/state of device
                OCFDevice.Resource resource = device.getResource(request.getResource().getUri());
                Log.d(TAG, "Get "+request.getResource().getUri()+" Resource's properties : " + device.getProperties(request.getResource().getUri()));

                if(resource!=null) {
                    Properties properties = resource.getProperties();
                    for (Enumeration<String> e = (Enumeration<String>)properties.propertyNames(); e.hasMoreElements() ;) {
                        String key = e.nextElement();
                        Object value = properties.get(key);
                        //Log.d(TAG, "Properties key="+key+", value="+value+", value instance="+ value.getClass().getCanonicalName());
                        service.msg("\t\t" + key + ": " + value);
                        if(value instanceof Boolean) {
                            root.setBoolean(key, (boolean)value);
                        } else if(value instanceof String) {
                            root.setTextString(key, (String)value);
                        } else if(value instanceof Integer || value instanceof Long) {
                            if(value instanceof Integer) root.setLong(key, (int)value);
                            else if(value instanceof Long) root.setLong(key, (long)value);
                        } else if(value instanceof Double || value instanceof Float) {
                            if(value instanceof Double) root.setDouble(key, (double)value);
                            else if(value instanceof Float) root.setDouble(key, (float)value);
                        }
                    }
                }
                break;
            default:
                break;
        }
        root.done();
        service.msg("Get "+request.getResource().getUri()+" Response Sent.");
        service.printLine();

        OcUtils.sendResponse(request, OCStatus.OC_STATUS_OK);
    }
}
