package com.bocloud.ims.service.utils;

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

import com.bocloud.common.model.BocloudResult;
import com.google.common.base.Preconditions;

/**
 * 数据存储结果的工具类
 *
 * @author sxp
 * @since 2017/11/13
 */
public class DataStoreUtils {

    /**
     * 校验二维表某一列数据非空
     *
     * @param data       二维表数据数据源，使用List、Map来模拟数据行、数据列和对应的数据
     * @param columnName 需要检验非空的列名，对应Map中的一个key值
     * @return 如果数据集合无数据，返回值中的属性success=true；
     * 如果数据集合有数据，只要存在一个数据为空，返回值中的属性success=false，message为具体哪几条数据为空；
     * 如果数据集合有数据，对应的列没有为空的数据，返回值中的属性success=true。
     */
    public static BocloudResult checkNotNull(List<Map<String, Object>> data, String columnName) {
        Preconditions.checkNotNull(data, "dataSource");
        Preconditions.checkNotNull(columnName, "columnName");

        Map<String, Object> row;
        Object v;
        boolean strIsNull;
        int count = data.size();
        StringBuilder errorMsg = new StringBuilder();

        for (int i = 0; i < count; i++) {
            row = data.get(i);
            if (!row.containsKey(columnName)) {
                errorMsg.append("第[").append(i + 1).append("]行数据的[").append(columnName).append("]缺失,");
                continue;
            }

            v = row.get(columnName);
            strIsNull = ((v instanceof String) && ((String) v).length() == 0);

            if (v == null || strIsNull) {
                errorMsg.append("第[").append(i + 1).append("]行数据的[").append(columnName).append("]不能为空,");
            }
        }

        if (errorMsg.length() > 0) {
            // 删除最后一个
            errorMsg.deleteCharAt(errorMsg.length() - 1);
            return new BocloudResult(false, errorMsg.toString());
        }

        return new BocloudResult(true, null);
    }

    /**
     * 校验二维表某一列数据不重复
     *
     * @param data       二维表数据数据源，使用List、Map来模拟数据行、数据列和对应的数据
     * @param columnName 需要检验的列名，对应Map中的一个key值
     * @return 如果数据集合无数据，返回值中的属性success=true；
     * 如果数据集合有数据，只要存在一个数据重复，返回值中的属性success=false，message为具体哪几条数据重复。
     * 特别地，在判断数据是否重复时，如果两个值同时为null，也判定为重复。
     */
    public static BocloudResult checkNotRepeat(List<Map<String, Object>> data, String columnName) {
        Preconditions.checkNotNull(data, "dataSource");
        Preconditions.checkNotNull(columnName, "columnName");

        Map<String, Object> row;
        Object value;
        int count = data.size();
        StringBuilder errorMsg = new StringBuilder();
        Map<Object, Integer> values = new HashMap<>(data.size());

        for (int i = 0; i < count; i++) {
            row = data.get(i);
            if (!row.containsKey(columnName)) {
                continue;
            }

            value = row.get(columnName);

            if (values.containsKey(value)) {
                errorMsg.append("第[").append(i + 1).append("]行数据的列[").append(columnName).append("]");
                errorMsg.append("与第[").append(values.get(value) + 1).append("]行重复,值同时为[");
                errorMsg.append(value).append("],");
            } else {
                // 数据的下标保存起来
                values.put(value, i);
            }
        }

        if (errorMsg.length() > 0) {
            // 删除最后一个,
            errorMsg.deleteCharAt(errorMsg.length() - 1);

            return new BocloudResult(false, errorMsg.toString());
        }

        return new BocloudResult(true, null);
    }
}
