/*
 * Copyright 1999-2015 dangdang.com.
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * </p>
 */

package com.dangdang.ddframe.rdb.sharding.api.fixture;

import com.dangdang.ddframe.rdb.sharding.api.rule.BindingTableRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.DataSourceRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.TableRule;
import com.dangdang.ddframe.rdb.sharding.api.strategy.database.DatabaseShardingStrategy;
import com.dangdang.ddframe.rdb.sharding.api.strategy.database.NoneDatabaseShardingAlgorithm;
import com.dangdang.ddframe.rdb.sharding.keygen.fixture.IncrementKeyGenerator;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterators;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import org.mockito.Mockito;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

public class ShardingRuleMockBuilder {
    
    private final List<String> shardingColumns = new ArrayList<>();
    
    private final Multimap<String, String> generateKeyColumnsMap = LinkedHashMultimap.create();
    
    private final List<String> bindTables = new ArrayList<>();
    
    public ShardingRuleMockBuilder addShardingColumns(final String shardingColumnName) {
        shardingColumns.add(shardingColumnName);
        return this;
    }
    
    public ShardingRuleMockBuilder addGenerateKeyColumn(final String tableName, final String columnName) {
        generateKeyColumnsMap.put(tableName, columnName);
        return this;
    }
    
    public ShardingRuleMockBuilder addBindingTable(final String bindingTableName) {
        bindTables.add(bindingTableName);
        return this;
    }
    
    public ShardingRule build() {
        final DataSourceRule dataSourceRule = new DataSourceRule(ImmutableMap.of("db0", Mockito.mock(DataSource.class), "db1", Mockito.mock(DataSource.class)));
        Collection<TableRule> tableRules = Lists.newArrayList(Iterators.transform(generateKeyColumnsMap.keySet().iterator(), new Function<String, TableRule>() {
            
            @Override
            public TableRule apply(final String input) {
                TableRule.TableRuleBuilder builder =  TableRule.builder(input).actualTables(Collections.singletonList(input)).dataSourceRule(dataSourceRule);
                for (String each : generateKeyColumnsMap.get(input)) {
                    builder.generateKeyColumn(each);
                }
                return builder.build();
            }
        }));
        if (tableRules.isEmpty()) {
            tableRules.add(new TableRule.TableRuleBuilder("mock").actualTables(Collections.singletonList("mock")).dataSourceRule(dataSourceRule).build());
        }
        List<TableRule> bindingTableRules = new ArrayList<>(bindTables.size());
        for (String each : bindTables) {
            bindingTableRules.add(new TableRule.TableRuleBuilder(each).actualTables(Collections.singletonList(each)).dataSourceRule(dataSourceRule).build());
        }
        for (TableRule each : tableRules) {
            bindingTableRules.add(each);
        }
        return new ShardingRule.ShardingRuleBuilder().dataSourceRule(dataSourceRule).keyGenerator(IncrementKeyGenerator.class)
                .tableRules(tableRules).bindingTableRules(Collections.singletonList(new BindingTableRule(bindingTableRules)))
                .databaseShardingStrategy(new DatabaseShardingStrategy(shardingColumns, new NoneDatabaseShardingAlgorithm())).build();
    }
}

@@ -1598,16 +1598,45 @@
 ctions;%0A
+import java.util.LinkedList;%0A
 import j
@@ -1691,24 +1691,96 @@
 lder %7B%0A    %0A
+    private final List%3CTableRule%3E tableRules = new LinkedList%3C%3E();%0A    %0A
     private 
@@ -1812,37 +1812,38 @@
 ngColumns = new 
-Array
+Linked
 List%3C%3E();%0A    %0A 
@@ -2006,24 +2006,169 @@
 t%3C%3E();%0A    %0A
+    public ShardingRuleMockBuilder addTableRules(final TableRule tableRule) %7B%0A        tableRules.add(tableRule);%0A        return this;%0A    %7D%0A    %0A
     public S
@@ -3491,24 +3491,68 @@
        %7D));%0A
+        tableRules.addAll(this.tableRules);%0A
         if (

add order table rule for all parsing test case