package ameba.db.ebean.jackson;

import ameba.db.ebean.EbeanPathProps;
import ameba.db.ebean.EbeanUtils;
import ameba.message.internal.BeanPathProperties;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonStreamContext;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import io.ebean.FetchPath;
import io.ebean.text.PathProperties;
import io.ebean.text.json.JsonContext;

import java.io.IOException;

/**
 * Serialise entity beans or collections.
 * <p>
 * Simply delegates to Ebean's JsonContext.
 * </p>
 *
 * @author icode
 *
 */
public class CommonBeanSerializer<T> extends JsonSerializer<T> {

    private final JsonContext jsonContext;


    /**
     * Construct with the given JsonContext.
     */
    CommonBeanSerializer(JsonContext jsonContext) {
        this.jsonContext = jsonContext;
    }

    /**
     * only first call return FetchPath
     * <p>
     * and then call is bean sub-path (property)
     *
     * @return fetch path or null
     */
    private FetchPath getPathProperties(JsonGenerator jsonGenerator) {
        FetchPath fetchPath = EbeanUtils.getRequestFetchPath();
        if (fetchPath != null) {
            JsonStreamContext context = jsonGenerator.getOutputContext();
            JsonStreamContext parent = context.getParent();
            if (parent == null) {
                return fetchPath;
            }
            StringBuilder path = new StringBuilder();
            while (parent != null && !parent.inRoot()) {
                if (parent != context.getParent()) {
                    path.insert(0, '.');
                }
                path.insert(0, parent.getCurrentName());
                parent = parent.getParent();
            }
            String fp = path.toString();
            PathProperties fetch = new PathProperties();
            EbeanPathProps src = (EbeanPathProps) fetchPath;
            String cp = fp + ".";
            for (BeanPathProperties.Props prop : src.getPathProps()) {
                String pp = prop.getPath();
                if (pp.equals(fp)) {
                    addToFetchPath(fetch, null, prop);
                } else if (pp.startsWith(cp)) {
                    addToFetchPath(fetch, pp.substring(cp.length()), prop);
                }
            }

            return fetch;
        }
        return null;
    }

    private void addToFetchPath(PathProperties fetchPath, String path, BeanPathProperties.Props prop) {
        for (String p : prop.getProperties()) {
            fetchPath.addToPath(path, p);
        }
    }

    /**
     * {@inheritDoc}
     *
     * Serialize entity beans or collections.
     */
    @Override
    public void serialize(T o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        final FetchPath pathProperties = getPathProperties(jsonGenerator);

        if (pathProperties != null) {
            jsonContext.toJson(o, jsonGenerator, pathProperties);
        } else {
            jsonContext.toJson(o, jsonGenerator);
        }
    }
}

@@ -470,37 +470,8 @@
 t;%0A%0A
-import java.io.IOException;%0A%0A
 /**%0A
@@ -591,19 +591,16 @@
 r icode%0A
- *%0A
  */%0Apubl
@@ -2046,32 +2046,70 @@
 prop.getPath();%0A
+                if (pp != null) %7B%0A    
                 
@@ -2125,24 +2125,28 @@
 uals(fp)) %7B%0A
+    
             
@@ -2200,24 +2200,28 @@
             
+   
+ 
 %7D else if (p
@@ -2236,24 +2236,28 @@
 With(cp)) %7B%0A
+    
             
@@ -2312,32 +2312,54 @@
 ngth()), prop);%0A
+                    %7D%0A
                 
@@ -2681,24 +2681,28 @@
 tDoc%7D%0A     *
+ %3Cp%3E
 %0A     * Seri
@@ -2758,16 +2758,16 @@
 verride%0A
+
     publ
@@ -2860,27 +2860,8 @@
 der)
- throws IOException
  %7B%0A 

update deps