/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

package org.apache.shardingsphere.core.parsing.integrate.asserts.token;

import com.google.common.base.Optional;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.core.parsing.integrate.asserts.SQLStatementAssertMessage;
import org.apache.shardingsphere.core.parsing.integrate.jaxb.token.ExpectedInsertValuesToken;
import org.apache.shardingsphere.core.parsing.integrate.jaxb.token.ExpectedTokens;
import org.apache.shardingsphere.core.parsing.parser.token.InsertValuesToken;
import org.apache.shardingsphere.core.parsing.parser.token.InsertValuesToken.InsertColumnValue;
import org.apache.shardingsphere.core.parsing.parser.token.SQLToken;

import java.util.Collection;

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

/**
 * Multiple insert values token assert.
 *
 * @author maxiaoguang
 */
@RequiredArgsConstructor
final class InsertValuesTokenAssert {
    
    private final SQLStatementAssertMessage assertMessage;
    
    void assertInsertValuesToken(final Collection<SQLToken> actual, final ExpectedTokens expected) {
        Optional<InsertValuesToken> insertValuesToken = getInsertValuesToken(actual);
        if (insertValuesToken.isPresent()) {
            assertInsertValuesToken(insertValuesToken.get(), expected.getInsertValuesToken());
        } else {
            assertNull(assertMessage.getFullAssertMessage("Insert values token should not exist: "), expected.getInsertValuesToken());
        }
    }
    
    private void assertInsertValuesToken(final InsertValuesToken actual, final ExpectedInsertValuesToken expected) {
        assertThat(assertMessage.getFullAssertMessage("Insert values token begin position assertion error: "), actual.getStartIndex(), is(expected.getBeginPosition()));
        assertThat(assertMessage.getFullAssertMessage("Insert values type assertion error: "), actual.getType().name(), is(expected.getType()));
        assertThat(assertMessage.getFullAssertMessage("Insert values column size assertion error: "), actual.getColumnValues().size(), is(expected.getInsertColumns().size()));
    
        for (InsertColumnValue each : actual.getColumnValues()) {
            assertThat(assertMessage.getFullAssertMessage("Insert values type assertion error: "), actual.getType().name(), is(expected.getType()));
        }
    }
    
    private Optional<InsertValuesToken> getInsertValuesToken(final Collection<SQLToken> actual) {
        for (SQLToken each : actual) {
            if (each instanceof InsertValuesToken) {
                return Optional.of((InsertValuesToken) each);
            }
        }
        return Optional.absent();
    }
}

@@ -865,24 +865,62 @@
 rts.token;%0A%0A
+import com.google.common.base.Joiner;%0A
 import com.g
@@ -1526,16 +1526,68 @@
 lection;
+%0Aimport java.util.LinkedList;%0Aimport java.util.List;
 %0A%0Aimport
@@ -2924,20 +2924,21 @@
  column 
-size
+names
  asserti
@@ -2943,32 +2943,53 @@
 tion error: %22), 
+Joiner.on(%22, %22).join(
 actual.getColumn
@@ -2992,22 +2992,15 @@
 lumn
-Values().size(
+Names()
 ), i
@@ -3017,28 +3017,19 @@
 .get
-InsertColumns().size
+ColumnNames
 ()))
@@ -3052,32 +3052,22 @@
 or (
-InsertColumnValue each :
+int i = 0; i %3C
  act
@@ -3087,16 +3087,28 @@
 Values()
+.size(); i++
 ) %7B%0A    
@@ -3165,36 +3165,38 @@
 age(%22Insert 
+column 
 values 
-type 
 assertion er
@@ -3208,54 +3208,311 @@
 %22), 
-actual.getType().name(), is(expected.getType()
+ is(expected.getType()));%0A        %7D%0A    %7D%0A    %0A    private String getInsertValues(final InsertColumnValue insertColumnValue, final int columnSize) %7B%0A        List%3CString%3E result = new LinkedList%3C%3E();%0A        for (int i = 0; i %3C columnSize; i++) %7B%0A            result.add(insertColumnValue.getColumnValue(0
 ));%0A
@@ -3513,32 +3513,77 @@
 (0));%0A        %7D%0A
+        return Joiner.on(%22, %22).join(result);%0A
     %7D%0A    %0A    p

add getInsertValues()