package com.gyee.dataadapter.dao_mqtt_influxdb_taos;

import com.gyee.dataadapter.dao.ILatestDao;
import com.gyee.dataadapter.dao.TsDataType;
import com.gyee.dataadapter.entity.PointData;
import com.gyee.dataadapter.service.IAdapterService;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.sql.Statement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Component
public class MqttTaosLatestDao implements ILatestDao {

    @Resource
    TaosConfig config;

    @Override
    public Map<String, PointData> getPointDataLatest(String... tagNames) {
        return new HashMap<>();
    }

    @Override
    public int writeDoubleLatest(List<PointData> list) {
        try {
            Statement st = config.getInstance().createStatement();
            StringBuilder sb = new StringBuilder();
            sb.append("INSERT INTO ");
            for (PointData obj : list) {
                sb.append(config.getDbName()).append(".").append(obj.getTagName()).append(" USING ")
                        .append(config.getDbName()).append(".").append(config.getAIStableName())
                        .append(" TAGS ('','','','','') VALUES (").append(obj.getTs())
                        .append(",").append(obj.getValue()).append(") ");
            }
            sb.append(";");
            val i = st.executeUpdate(sb.toString());

            return i == list.size() ? list.size() : 0;
        } catch (Exception e) {
            log.error(e.getMessage());
            return 0;
        }
    }

    @Override
    public int writeStringLatest(List<PointData> list) {
        return 0;
    }

    @Override
    public int writeBooleanLatest(List<PointData> list) {
        try {
            Statement st = config.getInstance().createStatement();
            StringBuilder sb = new StringBuilder();
            sb.append("insert into ");
            for (PointData obj : list) {
                long time = obj.getTs();
                String point = obj.getTagName();
                boolean value = obj.getValue() == 1;
                sb.append(point).append(" values (");
                sb.append(time).append(",").append(value).append(") ");
            }
            sb.append(";");
            return st.executeUpdate(sb.toString());
        } catch (Exception e) {
            log.error(e.getMessage());
            return 0;
        }
    }

    @Override
    public int writeLongLatest(List<PointData> list) {
        try {
            Statement st = config.getInstance().createStatement();
            StringBuilder sb = new StringBuilder();
            sb.append("insert into ");
            for (PointData obj : list) {
                long time = obj.getTs();
                String point = obj.getTagName();
                long value = obj.getLongValue();
                sb.append(point).append(" values (");
                sb.append(time).append(",").append(value).append(")");
            }
            boolean flag = st.execute(sb.toString());

            return flag == true ? list.size() : 0;
        } catch (Exception e) {
            log.error(e.getMessage());
            return 0;
        }
    }

    @Override
    public int writeBlobLatest(List<PointData> list) {
        return 0;
    }

    @Override
    public int writeCoordinateLatest(List<PointData> list) {
        return 0;
    }

    @Override
    public boolean writeLatest(List<PointData> dataList) {
        final int[] writeCount = {0};
        //dataList = dataList.stream().peek(tpd -> tpd.setTagName(tpd.getTagName().replaceFirst("\\.", "__"))).collect(Collectors.toList());
        Map<TsDataType, List<PointData>> pointGroup = dataList.stream().collect(Collectors.groupingBy(PointData::getDataType));
        pointGroup.forEach((type, pds) -> {
            if (type == TsDataType.DOUBLE) {
                int count = writeDoubleLatest(pds);
                writeCount[0] = writeCount[0] + count;
            } else if (type == TsDataType.BOOLEAN) {
                int count = writeBooleanLatest(pds);
                writeCount[0] = writeCount[0] + count;
            } else if (type == TsDataType.STRING) {
                int count = writeStringLatest(pds);
                writeCount[0] = writeCount[0] + count;
            } else if (type == TsDataType.BLOB) {
                int count = writeBlobLatest(pds);
                writeCount[0] = writeCount[0] + count;
            } else if (type == TsDataType.COORDINATE) {
                int count = writeCoordinateLatest(pds);
                writeCount[0] = writeCount[0] + count;
            } else if (type == TsDataType.LONG) {
                int count = writeLongLatest(pds);
                writeCount[0] = writeCount[0] + count;
            }
        });
        return writeCount[0] > 0 ? true : false;
    }
}
