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

import android.util.Pair;

import org.iotivity.OCClientResponse;
import org.iotivity.OCRep;
import org.iotivity.OCRepresentation;
import org.iotivity.bridge.homeserver.BridgeServerActivity;
import org.iotivity.bridge.homeserver.BridgeService;
import org.iotivity.bridge.homeserver.utils.Utils;
import org.iotivity.oc.OcRepresentation;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Arrays;

public class ResponseParsingHelper {

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

    static public String parseClientResponseToString(OCClientResponse response, BridgeServerActivity activity) {

        return Utils.propertiesToString(parseClientResponse(response, activity.getBridgeService()));
    }

    static public String parseClientResponseToString(OCClientResponse response, BridgeService service) {

        return Utils.propertiesToString(parseClientResponse(response, service));
    }

    static public ArrayList<Pair<String, Object>> parseClientResponse(OCClientResponse response, BridgeServerActivity activity) {

        return parseClientResponse(response, activity.getBridgeService());
    }

    static public ArrayList<Pair<String, Object>> parseClientResponse(OCClientResponse response, BridgeService service) {

        final ArrayList<Pair<String, Object>> props = new ArrayList<>();
        OCRepresentation rep = response.getPayload();
        while (rep != null) {
            service.msg("\t" + "Type" + " = " + rep.getType().name());
            switch (rep.getType()) {
                case OC_REP_BOOL:
                    service.msg("\t" + rep.getName() + " = " + rep.getValue().getBool());
                    props.add(new Pair(rep.getName(), rep.getValue().getBool()));
                    break;
                case OC_REP_INT:
                    service.msg("\t" + rep.getName() + " = " + rep.getValue().getInteger());
                    props.add(new Pair(rep.getName(), rep.getValue().getInteger()));
                    break;
                case OC_REP_STRING:
                    service.msg("\t" + rep.getName() + " = " + rep.getValue().getString());
                    props.add(new Pair(rep.getName(), rep.getValue().getString()));
                    break;
                case OC_REP_DOUBLE:
                    service.msg("\t" + rep.getName() + " = " + rep.getValue().getDouble());
                    props.add(new Pair(rep.getName(), rep.getValue().getDouble()));
                    break;
                case OC_REP_STRING_ARRAY:
                    String[] str_arr = OCRep.ocArrayToStringArray(rep.getValue().getArray());
                    String str_strs = Utils.toString(str_arr);
                    service.msg("\t" + rep.getName() + " = " + str_strs);
                    props.add(new Pair(rep.getName(), str_strs));
                    break ;
                case OC_REP_BOOL_ARRAY:
                    boolean[] bool_arr = OCRep.ocArrayToBooleanArray(rep.getValue().getArray());
                    String bool_strs = Utils.toString(bool_arr);
                    service.msg("\t" + rep.getName() + " = " + bool_strs);
                    props.add(new Pair(rep.getName(), bool_strs));
                    break;
                case OC_REP_INT_ARRAY:
                    long[] long_arr = OCRep.ocArrayToLongArray(rep.getValue().getArray());
                    String long_strs = Utils.toString(long_arr);
                    service.msg("\t" + rep.getName() + " = " + long_strs);
                    props.add(new Pair(rep.getName(), long_strs));
                    break;
                case OC_REP_DOUBLE_ARRAY:
                    double[] double_arr = OCRep.ocArrayToDoubleArray(rep.getValue().getArray());
                    String double_strs = Utils.toString(double_arr);
                    service.msg("\t" + rep.getName() + " = " + double_strs);
                    props.add(new Pair(rep.getName(), double_strs));
                    break;
                case OC_REP_OBJECT:
                {
                    OCRepresentation object = rep.getValue().getObject();
                    StringBuffer sb = new StringBuffer();
                    sb.append("{");
                    while (object != null) {
                        switch (object.getType()) {
                            case OC_REP_STRING:
                                sb.append(object.getName() + " = " + object.getValue().getString());
                                break;
                            default:
                                break;
                        }
                        object = object.getNext();
                        if (object != null) sb.append(", ");
                    }
                    sb.append("}");
                    service.msg("\t" + rep.getName() + " = " + sb.toString());
                    props.add(new Pair(rep.getName(), sb.toString()));
                }
                break;
                case OC_REP_OBJECT_ARRAY:
                {
                    OCRepresentation array = rep.getValue().getObject();
                    StringBuffer sb = new StringBuffer();
                    sb.append("[");
                    while (array != null) {
                        service.msg("\t" + "OC_REP_OBJECT_ARRAY Type" + " = " + array.getType().name());
                        switch (array.getType()) {
                            case OC_REP_OBJECT: {
                                OCRepresentation object = array.getValue().getObject();
                                sb.append("{");
                                while (object != null) {
                                    service.msg("\t" + "OC_REP_OBJECT Type" + " = " + object.getType().name());
                                    switch (object.getType()) {
                                        case OC_REP_STRING:
                                            sb.append(object.getName() + " = " + object.getValue().getString());
                                            break;
                                        case OC_REP_BOOL:
                                            sb.append(object.getName() + " = " + object.getValue().getBool());
                                            break;
                                        case OC_REP_INT:
                                            sb.append(object.getName() + " = " + object.getValue().getInteger());
                                            break;
                                        case OC_REP_DOUBLE:
                                            sb.append(object.getName() + " = " + object.getValue().getDouble());
                                            break;
                                        case OC_REP_STRING_ARRAY:
                                            service.msg("\tarray size = " + OCRep.ocArrayToStringArray(rep.getValue().getArray()).length);

                                            sb.append(object.getName() + " = " + Arrays.toString(OCRep.ocArrayToStringArray(rep.getValue().getArray())));
                                            break;
                                        case OC_REP_INT_ARRAY:
                                            sb.append(object.getName() + " = " + Arrays.toString(OCRep.ocArrayToLongArray(rep.getValue().getArray())));
                                            break;
                                        case OC_REP_DOUBLE_ARRAY:
                                            sb.append(object.getName() + " = " + Arrays.toString(OCRep.ocArrayToDoubleArray(rep.getValue().getArray())));
                                            break;
                                        case OC_REP_BOOL_ARRAY:
                                            sb.append(object.getName() + " = " + Arrays.toString(OCRep.ocArrayToBooleanArray(rep.getValue().getArray())));
                                            break;
                                        default:
                                            break;
                                    }
                                    object = object.getNext();
                                    if (object != null) sb.append(", ");
                                }
                                sb.append("}");
                            }
                            break;
                            default:
                                break;
                        }
                        array = array.getNext();
                        if (array != null) sb.append(", ");
                    }
                    sb.append("]");
                    service.msg("\t" + rep.getName() + " = " + sb.toString());
                    props.add(new Pair(rep.getName(), sb.toString()));
                }
                break;
                default:
                    break;
            }
            rep = rep.getNext();
        }
        service.printLine();

        return props ;
    }

}
