/*
 * 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.shardingproxy.transport.mysql.packet.command.admin.initdb;

import com.google.common.base.Optional;
import io.shardingsphere.core.constant.ShardingConstant;
import io.shardingsphere.shardingproxy.frontend.common.FrontendHandler;
import io.shardingsphere.shardingproxy.runtime.GlobalRegistry;
import io.shardingsphere.shardingproxy.transport.mysql.constant.ServerErrorCode;
import io.shardingsphere.shardingproxy.transport.mysql.packet.MySQLPacketPayload;
import io.shardingsphere.shardingproxy.transport.mysql.packet.command.CommandPacketType;
import io.shardingsphere.shardingproxy.transport.mysql.packet.command.CommandResponsePackets;
import io.shardingsphere.shardingproxy.transport.mysql.packet.generic.ErrPacket;
import io.shardingsphere.shardingproxy.transport.mysql.packet.generic.OKPacket;
import lombok.SneakyThrows;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public final class ComInitDbPacketTest {
    
    @Mock
    private MySQLPacketPayload payload;
    
    @Mock
    private FrontendHandler frontendHandler;
    
    @Before
    @SneakyThrows
    public void setUp() {
        List<String> schemaNames = new ArrayList<>(1);
        schemaNames.add(ShardingConstant.LOGIC_SCHEMA_NAME);
        Field field = GlobalRegistry.class.getDeclaredField("schemaNames");
        field.setAccessible(true);
        field.set(GlobalRegistry.getInstance(), schemaNames);
    }
    
    @Test
    public void assertExecuteWithValidSchemaName() {
        when(payload.readStringEOF()).thenReturn(ShardingConstant.LOGIC_SCHEMA_NAME);
        Optional<CommandResponsePackets> actual = new ComInitDbPacket(1, payload, frontendHandler).execute();
        assertTrue(actual.isPresent());
        assertThat(actual.get().getPackets().size(), is(1));
        assertThat(actual.get().getHeadPacket().getSequenceId(), is(2));
        assertThat(((OKPacket) actual.get().getHeadPacket()).getAffectedRows(), is(0L));
        assertThat(((OKPacket) actual.get().getHeadPacket()).getLastInsertId(), is(0L));
        assertThat(((OKPacket) actual.get().getHeadPacket()).getWarnings(), is(0));
        assertThat(((OKPacket) actual.get().getHeadPacket()).getInfo(), is(""));
    }
    
    @Test
    public void assertExecuteWithInvalidSchemaName() {
        String invalidSchema = "invalid_schema";
        when(payload.readStringEOF()).thenReturn(invalidSchema);
        Optional<CommandResponsePackets> actual = new ComInitDbPacket(1, payload, frontendHandler).execute();
        assertTrue(actual.isPresent());
        assertThat(actual.get().getPackets().size(), is(1));
        assertThat(actual.get().getHeadPacket().getSequenceId(), is(2));
        assertThat(((ErrPacket) actual.get().getHeadPacket()).getErrorCode(), is(ServerErrorCode.ER_BAD_DB_ERROR.getErrorCode()));
        assertThat(((ErrPacket) actual.get().getHeadPacket()).getSqlState(), is(ServerErrorCode.ER_BAD_DB_ERROR.getSqlState()));
        assertThat(((ErrPacket) actual.get().getHeadPacket()).getErrorMessage(), is(String.format(ServerErrorCode.ER_BAD_DB_ERROR.getErrorMessage(), invalidSchema)));
    }
    
    @Test
    public void assertWrite() {
        when(payload.readStringEOF()).thenReturn(ShardingConstant.LOGIC_SCHEMA_NAME);
        ComInitDbPacket actual = new ComInitDbPacket(1, payload, frontendHandler);
        assertThat(actual.getSequenceId(), is(1));
        actual.write(payload);
        verify(payload).writeInt1(CommandPacketType.COM_INIT_DB.getValue());
        verify(payload).writeStringEOF(ShardingConstant.LOGIC_SCHEMA_NAME);
    }
}

@@ -931,16 +931,83 @@
 gistry;%0A
+import io.shardingsphere.shardingproxy.runtime.schema.LogicSchema;%0A
 import i
@@ -1734,25 +1734,27 @@
 va.util.
-ArrayList
+Collections
 ;%0Aimport
@@ -1764,20 +1764,19 @@
 va.util.
-List
+Map
 ;%0A%0Aimpor
@@ -1900,16 +1900,56 @@
 rtTrue;%0A
+import static org.mockito.Mockito.mock;%0A
 import s
@@ -2287,78 +2287,72 @@
     
-List
+Map
 %3CString
-%3E schemaNames = new ArrayList%3C%3E(1);%0A        schemaNames.add
+, LogicSchema%3E logicSchemas = Collections.singletonMap
 (Sha
@@ -2374,32 +2374,57 @@
 OGIC_SCHEMA_NAME
+, mock(LogicSchema.class)
 );%0A        Field
@@ -2471,26 +2471,27 @@
 dField(%22
-s
+logicS
 chema
-Name
 s%22);%0A   
@@ -2574,18 +2574,19 @@
 (), 
-s
+logicS
 chema
-Name
 s);%0A

modify ComInitDbPacketTest.java