/*
 * Copyright 2016-2018 shardingsphere.io.
 * <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 io.shardingsphere.core.parsing.integrate.asserts.item;

import io.shardingsphere.core.parsing.integrate.asserts.SQLStatementAssertMessage;
import io.shardingsphere.core.parsing.integrate.jaxb.item.ExpectedDistinctSelectItem;
import io.shardingsphere.core.parsing.parser.context.selectitem.DistinctSelectItem;
import io.shardingsphere.core.parsing.parser.context.selectitem.SelectItem;
import lombok.RequiredArgsConstructor;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

/**
 * Distinct select item assert.
 *
 * @author panjuan
 */
@RequiredArgsConstructor
final class DistinctSelectItemAssert {
    
    private final SQLStatementAssertMessage assertMessage;
    
    void assertDistinctSelectItems(final Set<SelectItem> actual, final List<ExpectedDistinctSelectItem> expected) {
        List<DistinctSelectItem> distinctSelectItems = getDistinctSelectItems(actual);
        assertThat(assertMessage.getFullAssertMessage("distinct select items size error: "), distinctSelectItems.size(), is(expected.size()));
        int count = 0;
        for (DistinctSelectItem each : distinctSelectItems) {
            assertDistinctSelectItem(each, expected.get(count));
            count++;
        }
    }
    
    private void assertDistinctSelectItem(final DistinctSelectItem actual, final ExpectedDistinctSelectItem expected) {
        assertThat(assertMessage.getFullAssertMessage("Distinct select item alias assertion error: "), actual.getAlias().orNull(), is(expected.getAlias()));
        assertThat(assertMessage.getFullAssertMessage("Distinct select item distinct column name size assertion error: "),
                actual.getDistinctColumnNames().size(), is(expected.getDistinctColumnNames().size()));
        int count = 0;
        for (String each : actual.getDistinctColumnNames()) {
            assertThat(assertMessage.getFullAssertMessage("Distinct select item distinct column name assertion error: "), each, is(expected.getDistinctColumnNames().get(count)));
            count++;
        }
    }
    
    private List<DistinctSelectItem> getDistinctSelectItems(final Set<SelectItem> actual) {
        List<DistinctSelectItem> result = new ArrayList<>(actual.size());
        for (SelectItem each : actual) {
            if (each instanceof DistinctSelectItem) {
                result.add((DistinctSelectItem) each);
            }
        }
        return result;
    }
}

@@ -677,16 +677,96 @@
 .item;%0A%0A
+import com.google.common.base.Predicate;%0Aimport com.google.common.collect.Sets;%0A
 import i
@@ -1130,59 +1130,8 @@
 r;%0A%0A
-import java.util.ArrayList;%0Aimport java.util.List;%0A
 impo
@@ -1503,21 +1503,16 @@
 , final 
-List%3C
 Expected
@@ -1529,17 +1529,16 @@
 lectItem
-%3E
  expecte
@@ -1554,34 +1554,15 @@
     
-List%3CDistinctSelectItem%3E d
+assertD
 isti
@@ -1578,12 +1578,9 @@
 Item
-s = 
+(
 getD
@@ -1600,17 +1600,16 @@
 Item
-s
 (actual)
 ;%0A  
@@ -1608,333 +1608,20 @@
 ual)
-;%0A        assertThat(assertMessage.getFullAssertMessage(%22distinct select items size error: %22), distinctSelectItems.size(), is(expected.size()));%0A        int count = 0;%0A        for (DistinctSelectItem each : distinctSelectItems) %7B%0A            assertDistinctSelectItem(each, expected.get(count));%0A            count++;%0A        %7D
+, expected);
 %0A   
@@ -2449,21 +2449,16 @@
 private 
-List%3C
 Distinct
@@ -2467,17 +2467,16 @@
 lectItem
-%3E
  getDist
@@ -2481,33 +2481,32 @@
 stinctSelectItem
-s
 (final Set%3CSelec
@@ -2530,21 +2530,24 @@
         
-List%3C
+return (
 Distinct
@@ -2560,132 +2560,122 @@
 Item
-%3E result = new ArrayList%3C%3E(actual.size());%0A        for (SelectItem each : actual) %7B%0A            if (each instanceof Distinct
+) (Sets.filter(actual, new Predicate%3CSelectItem%3E() %7B%0A            @Override%0A            public boolean apply(final 
 Sele
@@ -2680,16 +2680,22 @@
 lectItem
+ input
 ) %7B%0A    
@@ -2712,18 +2712,30 @@
   re
-sult.add((
+turn input instanceof 
 Dist
@@ -2752,15 +2752,8 @@
 Item
-) each)
 ;%0A  
@@ -2777,30 +2777,28 @@
    %7D
-%0A        return result
+).iterator().next())
 ;%0A  

modify DistinctSelectItemAssert