package com.tmerclub.cloud.common.sharding.proxy.order;

import com.tmerclub.cloud.common.sharding.proxy.ShardingAlgorithmHelper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.shardingsphere.sharding.api.sharding.complex.ComplexKeysShardingAlgorithm;
import org.apache.shardingsphere.sharding.api.sharding.complex.ComplexKeysShardingValue;

import java.util.Collection;

/**
 * 自定义复合分表策略算法
 * @author tmerclub
 * @version 1.0
 */
public class CustomTableComplexKeysShardingAlgorithm implements ComplexKeysShardingAlgorithm<Long> {

    /**
     * 分片键优先级依次为：
     * order_id、user_id、refund_id
     * 维度，订单号、售后单号，他们的三个字段的后三位都是userid后三位
     * 虽然是多字段路由，但最后都是取的userId的后三位
     *
     * @param tableNames 表名
     * @param shardingValue 分片键信息
     * @return 匹配的数据源集合
     */
    @Override
    public Collection<String> doSharding(Collection<String> tableNames,
                                         ComplexKeysShardingValue<Long> shardingValue) {
        Collection<Long> orderIds = shardingValue.getColumnNameAndShardingValuesMap().get("order_id");
        if (CollectionUtils.isNotEmpty(orderIds)) {
            return ShardingAlgorithmHelper.getTableNames(tableNames, orderIds);
        }
        Collection<Long> orderItemIds = shardingValue.getColumnNameAndShardingValuesMap().get("order_item_id");
        if (CollectionUtils.isNotEmpty(orderItemIds)) {
            return ShardingAlgorithmHelper.getTableNames(tableNames, orderItemIds);
        }
        Collection<Long> orderInvoiceIds = shardingValue.getColumnNameAndShardingValuesMap().get("order_invoice_id");
        if (CollectionUtils.isNotEmpty(orderInvoiceIds)) {
            return ShardingAlgorithmHelper.getTableNames(tableNames, orderInvoiceIds);
        }
        Collection<Long> giveawayOrderItemIds = shardingValue.getColumnNameAndShardingValuesMap().get("giveaway_order_item_id");
        if (CollectionUtils.isNotEmpty(giveawayOrderItemIds)) {
            return ShardingAlgorithmHelper.getTableNames(tableNames, giveawayOrderItemIds);
        }
        Collection<Long> settlementIds = shardingValue.getColumnNameAndShardingValuesMap().get("settlement_id");
        if (CollectionUtils.isNotEmpty(settlementIds)) {
            return ShardingAlgorithmHelper.getTableNames(tableNames, settlementIds);
        }
        Collection<Long> userIds = shardingValue.getColumnNameAndShardingValuesMap().get("user_id");
        if (CollectionUtils.isNotEmpty(userIds)) {
            return ShardingAlgorithmHelper.getTableNames(tableNames, userIds);
        }
        Collection<Long> refundIds = shardingValue.getColumnNameAndShardingValuesMap().get("refund_id");
        if (CollectionUtils.isNotEmpty(refundIds)) {
            return ShardingAlgorithmHelper.getTableNames(tableNames, refundIds);
        }
        Collection<Long> orderAddrIds = shardingValue.getColumnNameAndShardingValuesMap().get("order_addr_id");
        if (CollectionUtils.isNotEmpty(orderAddrIds)) {
            return ShardingAlgorithmHelper.getTableNames(tableNames, orderAddrIds);
        }
        Collection<Long> orderPreSaleInfoIds = shardingValue.getColumnNameAndShardingValuesMap().get("order_pre_sale_info_id");
        if (CollectionUtils.isNotEmpty(orderPreSaleInfoIds)) {
            return ShardingAlgorithmHelper.getTableNames(tableNames, orderPreSaleInfoIds);
        }
        Collection<Long> purchaseOrderIds = shardingValue.getColumnNameAndShardingValuesMap().get("purchase_order_id");
        if (CollectionUtils.isNotEmpty(purchaseOrderIds)) {
            return ShardingAlgorithmHelper.getTableNames(tableNames, purchaseOrderIds);
        }
        Collection<Long> purchaseItemIds = shardingValue.getColumnNameAndShardingValuesMap().get("purchase_item_id");
        if (CollectionUtils.isNotEmpty(purchaseItemIds)) {
            return ShardingAlgorithmHelper.getTableNames(tableNames, purchaseItemIds);
        }
        Collection<Long> purchaseOrderAddrIds = shardingValue.getColumnNameAndShardingValuesMap().get("purchase_order_addr_id");
        if (CollectionUtils.isNotEmpty(purchaseOrderAddrIds)) {
            return ShardingAlgorithmHelper.getTableNames(tableNames, purchaseOrderAddrIds);
        }
        Collection<Long> orderSelfStationIds = shardingValue.getColumnNameAndShardingValuesMap().get("order_self_station_id");
        if (CollectionUtils.isNotEmpty(orderSelfStationIds)) {
            return ShardingAlgorithmHelper.getTableNames(tableNames, orderSelfStationIds);
        }
        Collection<Long> orderVirtualInfoIds = shardingValue.getColumnNameAndShardingValuesMap().get("order_virtual_info_id");
        if (CollectionUtils.isNotEmpty(orderVirtualInfoIds)) {
            return ShardingAlgorithmHelper.getTableNames(tableNames, orderVirtualInfoIds);
        }
        Collection<Long> deliveryOrderIds = shardingValue.getColumnNameAndShardingValuesMap().get("delivery_order_id");
        if (CollectionUtils.isNotEmpty(deliveryOrderIds)) {
            return ShardingAlgorithmHelper.getTableNames(tableNames, deliveryOrderIds);
        }
        Collection<Long> deliveryOrderItemIds = shardingValue.getColumnNameAndShardingValuesMap().get("delivery_order_item_id");
        if (CollectionUtils.isNotEmpty(deliveryOrderItemIds)) {
            return ShardingAlgorithmHelper.getTableNames(tableNames, deliveryOrderItemIds);
        }
        Collection<Long> shopIds = shardingValue.getColumnNameAndShardingValuesMap().get("shop_id");
        if (CollectionUtils.isNotEmpty(shopIds)) {
            return ShardingAlgorithmHelper.getTableNames(tableNames, shopIds);
        }
        Collection<Long> allotOrderIds = shardingValue.getColumnNameAndShardingValuesMap().get("allot_order_id");
        if (CollectionUtils.isNotEmpty(allotOrderIds)) {
            return ShardingAlgorithmHelper.getTableNames(tableNames, allotOrderIds);
        }
        Collection<Long> allotOrderItemIds = shardingValue.getColumnNameAndShardingValuesMap().get("allot_order_item_id");
        if (CollectionUtils.isNotEmpty(allotOrderItemIds)) {
            return ShardingAlgorithmHelper.getTableNames(tableNames, allotOrderItemIds);
        }
        return null;
    }
    
}
