/*
 * 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.shardingproxy.context;

import org.apache.shardingsphere.core.constant.properties.ShardingPropertiesConstant;
import org.apache.shardingsphere.core.rule.Authentication;
import org.apache.shardingsphere.orchestration.internal.eventbus.ShardingOrchestrationEventBus;
import org.apache.shardingsphere.orchestration.internal.registry.config.event.AuthenticationChangedEvent;
import org.apache.shardingsphere.orchestration.internal.registry.config.event.PropertiesChangedEvent;
import org.apache.shardingsphere.orchestration.internal.registry.state.event.CircuitStateChangedEvent;
import org.junit.Test;

import java.util.Properties;

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

public final class ShardingProxyContextTest {
    
    @Test
    public void assertInit() {
        Authentication authentication = new Authentication("root", "root");
        Properties props = new Properties();
        props.setProperty(ShardingPropertiesConstant.SQL_SHOW.getKey(), Boolean.TRUE.toString());
        props.setProperty(ShardingPropertiesConstant.PROXY_TRANSACTION_TYPE.getKey(), "BASE");
        ShardingProxyContext.getInstance().init(authentication, props);
        assertThat(ShardingProxyContext.getInstance().getAuthentication(), is(authentication));
        assertTrue(ShardingProxyContext.getInstance().getShardingProperties().<Boolean>getValue(ShardingPropertiesConstant.SQL_SHOW));
        assertThat(ShardingProxyContext.getInstance().getShardingProperties().<String>getValue(ShardingPropertiesConstant.PROXY_TRANSACTION_TYPE), is("BASE"));
    }
    
    @Test
    public void assertRenewShardingProperties() {
        ShardingProxyContext.getInstance().init(new Authentication("root", "root"), new Properties());
        assertTrue(ShardingProxyContext.getInstance().getShardingProperties().getProps().isEmpty());
        Properties props = new Properties();
        props.setProperty(ShardingPropertiesConstant.SQL_SHOW.getKey(), Boolean.TRUE.toString());
        ShardingOrchestrationEventBus.getInstance().post(new PropertiesChangedEvent(props));
        assertFalse(ShardingProxyContext.getInstance().getShardingProperties().getProps().isEmpty());
    }
    
    @Test
    public void assertRenewAuthentication() {
        ShardingProxyContext.getInstance().init(new Authentication("root", "root"), new Properties());
        ShardingOrchestrationEventBus.getInstance().post(new AuthenticationChangedEvent(new Authentication("user", "pwd")));
        assertThat(ShardingProxyContext.getInstance().getAuthentication().getUsername(), is("user"));
        assertThat(ShardingProxyContext.getInstance().getAuthentication().getPassword(), is("pwd"));
    }
    
    @Test
    public void assertRenewCircuitState() {
        assertFalse(ShardingProxyContext.getInstance().isCircuitBreak());
        ShardingOrchestrationEventBus.getInstance().post(new CircuitStateChangedEvent(true));
        assertTrue(ShardingProxyContext.getInstance().isCircuitBreak());
        ShardingOrchestrationEventBus.getInstance().post(new CircuitStateChangedEvent(false));
    }
}

@@ -999,16 +999,65 @@
 cation;%0A
+import org.apache.shardingsphere.core.rule.User;%0A
 import o
@@ -1144,16 +1144,16 @@
 entBus;%0A
-
 import o
@@ -1772,24 +1772,69 @@
 ertInit() %7B%0A
+        User user = new User(%22root%22, %22db1%22);%0A
         Auth
@@ -1876,32 +1876,73 @@
 hentication(
+);%0A        authentication.getUsers().put(
 %22root%22, 
 %22root%22);%0A   
@@ -1929,22 +1929,20 @@
 %22root%22, 
-%22root%22
+user
 );%0A     
@@ -2704,24 +2704,184 @@
 perties() %7B%0A
+        User user = new User(%22root%22, %22db1%22);%0A        Authentication authentication = new Authentication();%0A        authentication.getUsers().put(%22root%22, user);%0A
         Shar
@@ -2908,37 +2908,33 @@
 Instance().init(
-new A
+a
 uthentication(%22r
@@ -2930,32 +2930,16 @@
 tication
-(%22root%22, %22root%22)
 , new Pr
@@ -3453,24 +3453,184 @@
 ication() %7B%0A
+        User user = new User(%22root%22, %22db1%22);%0A        Authentication authentication = new Authentication();%0A        authentication.getUsers().put(%22root%22, user);%0A
         Shar
@@ -3665,21 +3665,17 @@
 ().init(
-new A
+a
 uthentic
@@ -3683,24 +3683,8 @@
 tion
-(%22root%22, %22root%22)
 , ne
@@ -3792,41 +3792,148 @@
 ent(
-new Authentication(%22user%22, %22pwd%22)
+authentication));%0A        assertThat(ShardingProxyContext.getInstance().getAuthentication().getUsers().keySet().iterator().next(), is(%22root%22
 ));%0A
@@ -4017,20 +4017,43 @@
 User
-name
+s().get(%22root%22).getPassword
 (), is(%22
 user
@@ -4048,20 +4048,20 @@
 (), is(%22
-user
+root
 %22));%0A   
@@ -4134,32 +4134,64 @@
 on().get
-Password
+Users().get(%22root%22).getAuthorizedSchemas
 (), is(%22
 pwd%22));%0A
@@ -4186,11 +4186,11 @@
 is(%22
-pwd
+db1
 %22));

modify unit cases