/**************************************************************************************************
 * Copyright 2018 Qualcomm Technologies International, Ltd.                                       *
 **************************************************************************************************/

{% if "allplay" in schema_type %}
package com.qualcomm.qti.iotcontrollersdk.allplay.resource.attributes;
{% endif %}

{% if "iotsys" in schema_type %}
package com.qualcomm.qti.iotcontrollersdk.iotsys.resource.attributes;
{% endif %}


{% set mybool = [False] %}
{% for prop, prop_data in schema_data.props.items() %}
{% if ( is_prop_array_type(prop_data) ) and ( not mybool[0]) %}
{% set _ = mybool.append(not mybool.pop()) %}
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
{% endif %}
{% endfor %}
import java.util.stream.Stream;
import com.qualcomm.qti.iotcontrollersdk.ResourceAttributes;
import org.iotivity.base.OcRepresentation;
import org.iotivity.base.OcException;
import com.qualcomm.qti.iotcontrollersdk.controller.ResourceAttrUtils;
import com.qualcomm.qti.iotcontrollersdk.controller.interfaces.IResourceAttributes;

public class {{schema_data.name|class_name_syntax}}Attr implements IResourceAttributes {

{% for prop, prop_data in schema_data.props.items() %}
{% if 'enum' in prop_data %}
    {{prop|enum_class}} {
{% for enum_name in prop_data['enum'] %}
        {{enum_name|enum_constant}},
{% endfor %}
    }

{% endif %}
{% endfor %}

{% for prop, prop_data in schema_data.props.items() %}
    public {{prop_data | convert_to_java_type(prop)}} {{prop|java_instance_variable_syntax}};
{% endfor %}

     public {{schema_data.name|class_name_syntax}}Attr() {
{% for prop, prop_data in schema_data.props.items() %}
{% if 'enum' not in prop_data %}
        {{prop | java_instance_variable_syntax}} = {{prop_data |default_value_java_type(prop)}};
{% else %}
        {{prop | java_instance_variable_syntax}} = {{prop|class_name_syntax}}.{{prop_data['enum'][0]|enum_constant}};
{% endif %}
{% endfor %}
     }

     @Override
     public OcRepresentation pack() throws OcException {
         OcRepresentation rep = new OcRepresentation();
         rep.setUri("/{{schema_data.name|local_variable}}_rep_uri");

{% if props_have_writable_object_array(schema_data.props) %}
         List<OcRepresentation> reps = new ArrayList<>();
{% endif %}
{% for prop, prop_data in schema_data.props.items() %}
{% if not 'readOnly' in prop_data or not prop_data['readOnly'] %}
{% if is_prop_an_object(prop_data) %}
         rep.setValue(ResourceAttributes.{{prop|java_prop_name}},{{prop|java_instance_variable_syntax}}.pack());
{% elif is_prop_an_object_array(prop_data) %}

         for ({{ prop_data|get_java_class_name }} elem : {{prop|java_instance_variable_syntax}}) {
           reps.add(elem.pack());
         }

         if (reps.size() > 0) {
            Stream<OcRepresentation> repStream = reps.stream();
            OcRepresentation[] repArray = repStream.toArray(size -> new OcRepresentation[size]);
            rep.setValue(ResourceAttributes.{{prop|java_prop_name}},repArray);
         }
{% else %}
{% if 'enum' in prop_data %}
         rep.setValue(ResourceAttributes.{{prop|java_prop_name}},{{prop|to_string_func}}({{pack_java_type(prop_data,prop)}}));
{% else %}
         rep.setValue(ResourceAttributes.{{prop|java_prop_name}},{{pack_java_type(prop_data,prop)}});
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
         return rep;
     }

     @Override
     public boolean unpack(OcRepresentation rep) throws OcException, NullPointerException  {
{% if props_have_object_array(schema_data.props) %}
        OcRepresentation[] reps;
{% endif %}
        boolean didUnpack = false;
        if(rep == null) return didUnpack;
        
{% for prop, prop_data in schema_data.props.items() %}
        if (rep.hasAttribute(ResourceAttributes.{{prop|java_prop_name}})) {
            didUnpack = true;
{% if is_prop_an_object(prop_data) %}
            {{ prop_data|convert_to_java_type(prop) }} obj = new {{ prop_data|convert_to_java_type(prop) }}();
            if(obj.unpack((OcRepresentation)rep.getValue(ResourceAttributes.{{prop|java_prop_name}})))
                {{prop|java_instance_variable_syntax}} = obj;
{% elif is_prop_an_object_array(prop_data) %}
            reps = rep.getValue(ResourceAttributes.{{prop|java_prop_name}});
            if(reps != null) {
                {{prop|java_instance_variable_syntax}}.clear();
                for (OcRepresentation elem_rep: reps) {
                    {{get_java_object_name_from_obj_array(prop_data)}} obj = new {{get_java_object_name_from_obj_array(prop_data)}}();
                    if(obj.unpack(elem_rep))
                        {{prop|java_instance_variable_syntax}}.add(obj);
                }
            }
{% else %}
{% if 'enum' in prop_data %}
            {{prop|java_instance_variable_syntax}} = {{prop|from_string_func}}({{unpack_java_type(prop_data, prop)}});
{% else %}
            {{prop|java_instance_variable_syntax}} = {{unpack_java_type(prop_data, prop)}};
{% endif %}
{% endif %}
        }
{% endfor %}
        return didUnpack;
    }

{% for prop, prop_data in schema_data.props.items() %}
{% if 'enum' in prop_data %}
    public {{prop|class_name_syntax}} {{prop|from_string_func}}(String value) {
        if(value != null) {
{% for enum_name in prop_data['enum'] %}
            if (value.equalsIgnoreCase("{{enum_name}}")) {
                return {{prop|class_name_syntax}}.{{enum_name|enum_constant}};
            }
{% endfor %}
        }
        return {{prop|class_name_syntax}}.{{prop_data['enum'][0]|enum_constant}};
    }

    public String {{prop|to_string_func}}({{prop|class_name_syntax}} value) {
        switch(value) {
{% for enum_name in prop_data['enum'] %}
            case {{enum_name|enum_constant}}:
                return "{{enum_name}}";
{% endfor %}
        }

        return "{{prop_data['enum'][0]}}";
    }

{% endif %}
{% endfor %}

   @Override
   public Object getData() {
    {{schema_data.name|class_name_syntax}}Attr clonedObj = new {{schema_data.name|class_name_syntax}}Attr();
{% for prop, prop_data in schema_data.props.items() %}
{% if is_prop_an_object(prop_data) %}
    clonedObj.{{prop|java_instance_variable_syntax}} = ({{prop_data|get_java_attribute_class_name}}){{prop|java_instance_variable_syntax}}.getData();
{% elif is_prop_an_object_array(prop_data) %}
    for({{prop_data|get_java_class_name}} item:{{prop|java_instance_variable_syntax}}) {
        clonedObj.{{prop|java_instance_variable_syntax}}.add(({{prop_data|get_java_class_name}})item.getData());
    }
{% else %}
    clonedObj.{{prop|java_instance_variable_syntax}} = this.{{prop|java_instance_variable_syntax}};
{% endif %}
{% endfor %}
    return clonedObj;
   }

   @Override
   public void setData(Object state) {
     if(state instanceof {{schema_data.name|class_name_syntax}}Attr) {
        {{schema_data.name|class_name_syntax}}Attr obj = ({{schema_data.name|class_name_syntax}}Attr) state;
{% for prop, prop_data in schema_data.props.items() %}
{% if is_prop_an_object(prop_data) %}
        this.{{prop|java_instance_variable_syntax}}.setData(obj.{{prop|java_instance_variable_syntax}});
{% elif is_prop_an_object_array(prop_data) %}
        this.{{prop|java_instance_variable_syntax}}.clear();
        for({{prop_data|get_java_class_name}} item:obj.{{prop|java_instance_variable_syntax}}) {
            this.{{prop|java_instance_variable_syntax}}.add(({{prop_data|get_java_class_name}})item.getData());
        }
{% else %}
        this.{{prop|java_instance_variable_syntax}} = obj.{{prop|java_instance_variable_syntax}};
{% endif %}
{% endfor %}
    }
   }

   @Override
   public boolean checkDifference(OcRepresentation rep) throws OcException {
{% if props_have_object_array(schema_data.props) %}
        OcRepresentation[] reps;
{% endif %}
        if(rep == null) return false;
        boolean didChanged;
{% for prop, prop_data in schema_data.props.items() %}
        if (rep.hasAttribute(ResourceAttributes.{{prop|java_prop_name}})) {
{% if is_prop_an_object(prop_data) %}
            didChanged = ({{prop|java_instance_variable_syntax}}.checkDifference(rep.getValue(ResourceAttributes.{{prop|java_prop_name}})));
            if(didChanged) return true;
{% elif is_prop_an_object_array(prop_data) %}
            reps = rep.getValue(ResourceAttributes.{{prop|java_prop_name}});
            if(reps != null) {
                if({{prop|java_instance_variable_syntax}}.size() != reps.length)
                    return true;
                else {
                    for (int i=0; i < reps.length; i++) {
                        if({{prop|java_instance_variable_syntax}}.get(i).checkDifference(reps[i]))
                            return true;
                    }
                }
            }
{% else %}
{% if 'enum' in prop_data %}
            didChanged = ({{prop|java_instance_variable_syntax}} != {{prop|from_string_func}}({{unpack_java_type(prop_data, prop)}}));
            if(didChanged) return true;
{% else %}
            didChanged = ({{diff_java_type(prop_data, prop)}});
            if(didChanged) return true;
{% endif %}
{% endif %}
        }
{% endfor %}
        return false;
   }
}
