package com.sinewang.kiimate.status.core.fui;

import one.kii.kiimate.model.core.dai.IntensionDai;
import one.kii.kiimate.status.core.dai.InstanceDai;
import one.kii.kiimate.status.core.fui.InstanceTransformer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by WangYanJiong on 21/05/2017.
 */
@Component
public class DefaultInstanceTransformer implements InstanceTransformer {

    @Autowired
    private IntensionDai intensionDai;

    @Override
    public Map<String, Object> toTimedValue(List<InstanceDai.Instance> instancesList, String rootExtId) {
        Map<String, List<InstanceDai.Instance>> dict = dict(instancesList);
        Map<String, Object> map = parseTimed(rootExtId, dict);
        return map;
    }

    @Override
    public Map<String, Object> toRawValue(List<InstanceDai.Instance> instancesList, String rootExtId) {
        Map<String, List<InstanceDai.Instance>> dict = dict(instancesList);
        Map<String, Object> map = parseRaw(rootExtId, dict);
        return map;
    }

    private Map<String, Object> parseRaw(String extId, Map<String, List<InstanceDai.Instance>> dict) {
        List<IntensionDai.Intension> intensions = intensionDai.selectIntensionsByExtId(extId);
        Map<String, Object> result = new HashMap<>();
        for (IntensionDai.Intension intension : intensions) {
            if (intension.isSingle()) {
                if (intension.getRefExtId() != null) {
                    Map<String, Object> child = parseRaw(intension.getRefExtId(), dict);
                    if (!child.isEmpty()) {
                        result.put(intension.getField(), child);
                    }
                } else {
                    List<InstanceDai.Instance> instances = dict.get(intension.getField());
                    if (instances != null && !instances.isEmpty()) {
                        Object value = dict.get(intension.getField()).get(0).getValue();
                        if (value != null) {
                            result.put(intension.getField(), value);
                        }
                    }
                }
            } else {
                if (intension.getRefExtId() != null) {
                    Map<String, Object> child = parseTimed(intension.getRefExtId(), dict);
                    if (!child.isEmpty()) {
                        addComplexValueToList(result, intension, child);
                    }
                } else {
                    List<InstanceDai.Instance> instances = dict.get(intension.getField());
                    if (instances != null && !instances.isEmpty()) {
                        for (InstanceDai.Instance instance : instances) {
                            if (instance.getValue() != null) {
                                List values = (List) result.get(intension.getField());
                                if (values == null) {
                                    values = new ArrayList<>();
                                    result.put(intension.getField(), values);
                                }
                                values.add(instance.getValue());
                            }
                        }
                    }
                }

            }
        }
        return result;
    }


    private Map<String, Object> parseTimed(String extId, Map<String, List<InstanceDai.Instance>> dict) {
        List<IntensionDai.Intension> intensions = intensionDai.selectIntensionsByExtId(extId);
        Map<String, Object> result = new HashMap<>();
        for (IntensionDai.Intension intension : intensions) {
            if (intension.isSingle()) {
                if (intension.getRefExtId() != null) {
                    Map<String, Object> child = parseTimed(intension.getRefExtId(), dict);
                    if (!child.isEmpty()) {
                        result.put(intension.getField(), child);
                    }
                } else {
                    List<InstanceDai.Instance> instances = dict.get(intension.getField());
                    if (instances != null && !instances.isEmpty()) {
                        Object value = dict.get(intension.getField()).get(0).getValue();
                        if (value != null) {
                            TimedValue tv = new TimedValue();
                            tv.setValue(value);
                            tv.setTime(dict.get(intension.getField()).get(0).getBeginTime());
                            result.put(intension.getField(), tv);
                        }
                    }
                }
            } else {
                if (intension.getRefExtId() != null) {
                    Map<String, Object> child = parseTimed(intension.getRefExtId(), dict);
                    addComplexValueToList(result, intension, child);
                } else {
                    List<InstanceDai.Instance> instances = dict.get(intension.getField());
                    if (instances != null && !instances.isEmpty()) {
                        for (InstanceDai.Instance instance : instances) {
                            if (instance.getValue() != null) {
                                Object v = instance.getValue();
                                TimedValue tv = new TimedValue();
                                tv.setValue(v);
                                tv.setTime(instance.getBeginTime());
                                result.computeIfAbsent(instance.getField(), key -> new ArrayList<>());
                                List values = (List) result.get(intension.getField());
                                values.add(tv);
                            }
                        }
                    }
                }

            }
        }
        return result;
    }


    private void addComplexValueToList(Map<String, Object> result, IntensionDai.Intension intension, Map<String, Object> child) {
        if (!child.isEmpty()) {
            List values = (List) result.get(intension.getField());
            if (values == null) {
                values = new ArrayList<>();
                result.put(intension.getField(), values);
            }
            values.add(child);
        }
    }

    private Map<String, List<InstanceDai.Instance>> dict(List<InstanceDai.Instance> instances) {
        Map<String, List<InstanceDai.Instance>> dict = new HashMap<>();
        for (InstanceDai.Instance instance : instances) {
            if (instance.getValueSetHash() == null) {
                List<InstanceDai.Instance> values = new ArrayList<>();
                values.add(instance);
                dict.put(instance.getField(), values);
            } else {
                dict.computeIfAbsent(instance.getField(), key -> new ArrayList<>());
                List<InstanceDai.Instance> values = dict.get(instance.getField());
                values.add(instance);
            }
        }
        return dict;
    }

}

@@ -2922,161 +2922,58 @@
     
-List values = (List) result.get(intension.getField());%0A                                if (values == null) %7B%0A                                    values =
+result.computeIfAbsent(instance.getField(), key -%3E
  new
@@ -2978,32 +2978,33 @@
 ew ArrayList%3C%3E()
+)
 ;%0A              
@@ -3017,35 +3017,52 @@
             
-   
+List values = (List)
  result.
 put(intensio
@@ -3041,34 +3041,34 @@
 = (List) result.
-pu
+ge
 t(intension.getF
@@ -3077,52 +3077,10 @@
 ld()
-, values);%0A                                %7D
+);
 %0A   
@@ -5954,121 +5954,59 @@
     
-List values = (List) result.get(intension.getField());%0A            if (values == null) %7B%0A                values =
+result.computeIfAbsent(intension.getField(), key -%3E
  new
@@ -6011,32 +6011,33 @@
 ew ArrayList%3C%3E()
+)
 ;%0A              
@@ -6030,35 +6030,52 @@
             
-   
+List values = (List)
  result.
 put(intensio
@@ -6054,34 +6054,34 @@
 = (List) result.
-pu
+ge
 t(intension.getF
@@ -6090,32 +6090,10 @@
 ld()
-, values);%0A            %7D
+);
 %0A   

use computeIfAbsent