package org.nl.acs.udw.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.nl.acs.udw.UdwConfig;
import org.nl.acs.udw.UnifiedData;
import org.nl.acs.udw.UnifiedDataAppService;
import org.nl.common.exception.BadRequestException;

import java.util.*;

@Slf4j
public class UnifiedDataAppServiceImpl implements UnifiedDataAppService {
    public static UnifiedDataAppService unifiedDataAppService;
    private Map<String, UnifiedDataUnit> factory = Collections.synchronizedMap(new HashMap());

    private UnifiedDataAppServiceImpl() {
    }

    public static UnifiedDataAppService getInstance() {
        if (unifiedDataAppService == null) {
            Class var0 = UnifiedDataAppServiceImpl.class;
            synchronized (UnifiedDataAppServiceImpl.class) {
                if (unifiedDataAppService == null) {
                    unifiedDataAppService = new UnifiedDataAppServiceImpl();
                }
            }
        }
        return unifiedDataAppService;
    }

    public List<String> getAllUnifiedKey() {
        return new ArrayList(this.factory.keySet());
    }

    public UnifiedDataUnit getUnifiedDataUnit(String unified_key) {
        UnifiedDataUnit dataUnit = (UnifiedDataUnit) this.factory.get(unified_key);
        return dataUnit == null ? null : dataUnit;
    }

    public List<String> getAllDataKey(String unified_key) {
        UnifiedDataUnit dataUnit = (UnifiedDataUnit) this.factory.get(unified_key);
        if (dataUnit == null) {
            return new ArrayList();
        } else {
            Map<String, UnifiedData> storage = dataUnit.getStorage();
            return new ArrayList(storage.keySet());
        }
    }

    public UnifiedData getUnifiedData(String unified_key, String key) {
        UnifiedDataUnit dataUnit = this.getUnifiedDataUnit(unified_key);
        if (dataUnit == null) {
            return null;
        } else {
            Map<String, UnifiedData> storage = dataUnit.getStorage();
            return (UnifiedData) storage.get(key);
        }
    }

    public Object getValue(String unified_key, String key) {
        UnifiedData unifiedData = this.getUnifiedData(unified_key, key);
        return unifiedData == null ? null : unifiedData.getValue();
    }

    public void removeValueWithPersistence(String unified_key, String key) {
        UnifiedDataUnit dataUnit = this.getUnifiedDataUnit(unified_key);
        if (dataUnit != null) {
            Map<String, UnifiedData> storage = dataUnit.getStorage();
            if (storage.containsKey(key)) {
                storage.remove(key);
            }

            Map<String, List<UnifiedData>> history = dataUnit.getHistory();
            if (history.containsKey(key)) {
                history.remove(key);
            }

            /*PersistenceService persistenceService = PersistenceServiceFactory.getPersistenceService();
            persistenceService.deleteData(unified_key, key);*/
        }
    }

    public void removeValue(String unified_key, String key) {
        UnifiedDataUnit dataUnit = this.getUnifiedDataUnit(unified_key);
        if (dataUnit != null) {
            Map<String, UnifiedData> storage = dataUnit.getStorage();
            if (storage.containsKey(key)) {
                storage.remove(key);
            }

            Map<String, List<UnifiedData>> history = dataUnit.getHistory();
            if (history.containsKey(key)) {
                history.remove(key);
            }

            if (history.size() == 0) {
                this.factory.remove(unified_key);
            }

        }
    }

    public void setValueNoLog(String unified_key, String key, Object value) {
        this.setValue(unified_key, key, value, false, false);
    }

    public void setValue(String unified_key, String key, Object value) {
        this.setValue(unified_key, key, value, false, true);
    }

    public void setValueWithPersistenceNoLog(String unified_key, String key, Object value) {
        this.setValue(unified_key, key, value, true, false);
    }

    public void setValueWithPersistence(String unified_key, String key, Object value) {
        this.setValue(unified_key, key, value, true, true);
    }

    public synchronized void setValue(String unified_key, String key, Object value, boolean save, boolean is_log) {
        if (unified_key == null) {
            throw new BadRequestException("");
            //throw new BusinessException(SystemMessage.cant_be_empty, new Object[]{"unified_key"});
        } else if (key == null) {
            throw new BadRequestException("");
            //throw new BusinessException(SystemMessage.cant_be_empty, new Object[]{"key"});
        } else {
            if (!this.factory.containsKey(unified_key)) {
                this.factory.put(unified_key, new UnifiedDataUnit(unified_key));
            }

            UnifiedDataUnit dataUnit = (UnifiedDataUnit) this.factory.get(unified_key);
            Map<String, UnifiedData> storage = dataUnit.getStorage();
            if (!storage.containsKey(key)) {
                storage.put(key, new UnifiedData());
            }

            UnifiedData unifiedData = (UnifiedData) storage.get(key);
            if (!UnifiedDataAppService.isEquals(unifiedData.getValue(), value)) {
                Map<String, List<UnifiedData>> history = dataUnit.getHistory();
                List<UnifiedData> historyunifiedData = (List) history.get(key);
                if (historyunifiedData == null) {
                    history.put(key, new ArrayList());
                }

                UnifiedData historydata = new UnifiedData();
                historydata.setLast_modify_date(unifiedData.getLast_modify_date());
                historydata.setValue(unifiedData.getValue());

                while (((List) history.get(key)).size() > UdwConfig.max_history_length) {
                    ((List) history.get(key)).remove(UdwConfig.max_history_length);
                }

                ((List) history.get(key)).add(0, historydata);
                Object oldvalue = unifiedData.getValue();
                unifiedData.changeValue(value);
                if (save) {
                    /*PersistenceService persistenceService = PersistenceServiceFactory.getPersistenceService();
                    persistenceService.saveData(unified_key, key, StringUtl.getString(value));
                    if (is_log) {
                        this.businessLogger.setResource(unified_key, unified_key);
                        this.businessLogger.setMaterial(key, key);
                        this.businessLogger.setContainer(StringUtl.getString(value));
                        this.businessLogger.log("统一数据源中: unit: {}, key: {}, 值: {} 更改为 {}。", new Object[]{unified_key, key, oldvalue, value});
                    }*/
                }

                if (is_log && key != null && !key.endsWith("heartbeat") && !key.endsWith("distancex") && !key.endsWith("distancey") && !key.endsWith("Xwz") && !key.endsWith("Ywz") && !key.endsWith("Zwz")) {
                    log.trace("统一数据源中: unit: {}, key: {}, 值: {} 更改为 {}。", new Object[]{unified_key, key, oldvalue, value});
                }
            }

        }
    }

    public List<UnifiedData> getHistoryUnifiedData(String unified_key, String key) {
        UnifiedDataUnit dataUnit = this.getUnifiedDataUnit(unified_key);
        if (dataUnit == null) {
            return new ArrayList();
        } else {
            Map<String, List<UnifiedData>> history = dataUnit.getHistory();
            List<UnifiedData> result = (List) history.get(key);
            return (List) (result == null ? new ArrayList() : result);
        }
    }
}
