/*
 * Copyright 2017-2018, EnMasse authors.
 * License: Apache License 2.0 (see the file LICENSE or http://apache.org/licenses/LICENSE-2.0.html).
 */
package io.enmasse.address.model.v1;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.enmasse.address.model.Address;
import io.enmasse.address.model.Status;

import java.io.IOException;
import java.util.Iterator;

/**
 * Deserializer for Address V1 format
 */
class AddressV1Deserializer extends JsonDeserializer<Address> {
    private static final ObjectMapper mapper = new ObjectMapper();

    @Override
    public Address deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        ObjectNode root = mapper.readValue(jsonParser, ObjectNode.class);
        return deserialize(root);
    }

    Address deserialize(ObjectNode root) {
        ObjectNode metadata = (ObjectNode) root.get(Fields.METADATA);
        ObjectNode spec = (ObjectNode) root.get(Fields.SPEC);
        ObjectNode status = (ObjectNode) root.get(Fields.STATUS);

        String type = spec.get(Fields.TYPE).asText();

        Address.Builder builder = new Address.Builder()
                .setAddress(spec.get(Fields.ADDRESS).asText())
                .setType(type)
                .setPlan(spec.get(Fields.PLAN).asText());

        if (metadata.hasNonNull(Fields.NAME)) {
            builder.setName(metadata.get(Fields.NAME).asText());
        }

        if (metadata.hasNonNull(Fields.ADDRESS_SPACE)) {
            builder.setAddressSpace(metadata.get(Fields.ADDRESS_SPACE).asText());
        }

        if (metadata.hasNonNull(Fields.UUID)) {
            builder.setUuid(metadata.get(Fields.UUID).asText());
        }

        if (metadata.hasNonNull(Fields.ANNOTATIONS)) {
            ObjectNode annotationObject = metadata.with(Fields.ANNOTATIONS);
            Iterator<String> annotationIt = annotationObject.fieldNames();
            while (annotationIt.hasNext()) {
                String key = annotationIt.next();
                if (annotationObject.get(key).isTextual()) {
                    builder.putAnnotation(key, annotationObject.get(key).asText());
                }
            }
        }

        if (status != null) {
            boolean isReady = status.get(Fields.IS_READY).asBoolean();
            Status s = new Status(isReady);

            if (status.hasNonNull(Fields.PHASE)) {
                s.setPhase(Status.Phase.valueOf(status.get(Fields.PHASE).asText()));
            }
            if (status.hasNonNull(Fields.MESSAGES)) {
                ArrayNode messages = (ArrayNode) status.get(Fields.MESSAGES);
                for (int i = 0; i < messages.size(); i++) {
                    s.appendMessage(messages.get(i).asText());
                }
            }
            builder.setStatus(s);
        }

        return builder.build();
    }
}

@@ -1575,24 +1575,60 @@
 asText());%0A%0A
+        if (metadata != null) %7B%0A    
         if (
@@ -1659,24 +1659,28 @@
 ds.NAME)) %7B%0A
+    
             
@@ -1732,32 +1732,36 @@
 ext());%0A        
+    
 %7D%0A%0A        if (m
@@ -1747,32 +1747,36 @@
      %7D%0A%0A        
+ 
+   
 if (metadata.has
@@ -1804,24 +1804,28 @@
 S_SPACE)) %7B%0A
+    
             
@@ -1898,35 +1898,42 @@
 ));%0A        
-%7D%0A%0A
+    %7D%0A%0A   
         
 if (metadata
@@ -1912,32 +1912,33 @@
   %7D%0A%0A           
+ 
 if (metadata.has
@@ -1957,24 +1957,28 @@
 ds.UUID)) %7B%0A
+    
             
@@ -2030,35 +2030,43 @@
 ext());%0A        
+   
+ 
 %7D%0A%0A
+    
         if (meta
@@ -2108,32 +2108,36 @@
 ) %7B%0A            
+  
+  
 ObjectNode annot
@@ -2197,16 +2197,20 @@
         
+    
 Iterator
@@ -2276,16 +2276,20 @@
         
+  
+  
 while (a
@@ -2309,24 +2309,28 @@
 asNext()) %7B%0A
+    
             
@@ -2379,24 +2379,28 @@
             
+ 
+   
 if (annotati
@@ -2428,24 +2428,28 @@
 extual()) %7B%0A
+    
             
@@ -2512,32 +2512,54 @@
 key).asText());%0A
+                    %7D%0A
                 

Allow null metadata