/*
 * 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.servicecomb.governance;

import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.servicecomb.governance.event.GovernanceConfigurationChangedEvent;
import org.apache.servicecomb.governance.event.GovernanceEventManager;
import org.apache.servicecomb.governance.marker.Matcher;
import org.apache.servicecomb.governance.marker.TrafficMarker;
import org.apache.servicecomb.governance.policy.AbstractPolicy;
import org.apache.servicecomb.governance.policy.BulkheadPolicy;
import org.apache.servicecomb.governance.policy.CircuitBreakerPolicy;
import org.apache.servicecomb.governance.policy.RateLimitingPolicy;
import org.apache.servicecomb.governance.policy.RetryPolicy;
import org.apache.servicecomb.governance.properties.BulkheadProperties;
import org.apache.servicecomb.governance.properties.CircuitBreakerProperties;
import org.apache.servicecomb.governance.properties.GovernanceProperties;
import org.apache.servicecomb.governance.properties.InstanceIsolationProperties;
import org.apache.servicecomb.governance.properties.MatchProperties;
import org.apache.servicecomb.governance.properties.RateLimitProperties;
import org.apache.servicecomb.governance.properties.RetryProperties;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.Environment;
import org.springframework.test.context.ContextConfiguration;

@SpringBootTest
@ContextConfiguration(classes = {GovernanceConfiguration.class, MockConfiguration.class})
public class GovernancePropertiesTest {
  private List<GovernanceProperties<? extends AbstractPolicy>> propertiesList;

  private MatchProperties matchProperties;

  private BulkheadProperties bulkheadProperties;

  private CircuitBreakerProperties circuitBreakerProperties;

  private InstanceIsolationProperties instanceIsolationProperties;

  private RateLimitProperties rateLimitProperties;

  private RetryProperties retryProperties;

  private Environment environment;

  @Autowired
  public void setPropertiesList(List<GovernanceProperties<? extends AbstractPolicy>> propertiesList) {
    this.propertiesList = propertiesList;
  }

  @Autowired
  public void setMatchProperties(MatchProperties matchProperties) {
    this.matchProperties = matchProperties;
  }

  @Autowired
  public void setBulkheadProperties(BulkheadProperties bulkheadProperties) {
    this.bulkheadProperties = bulkheadProperties;
  }

  @Autowired
  public void setCircuitBreakerProperties(CircuitBreakerProperties circuitBreakerProperties) {
    this.circuitBreakerProperties = circuitBreakerProperties;
  }

  @Autowired
  public void setRateLimitProperties(RateLimitProperties rateLimitProperties) {
    this.rateLimitProperties = rateLimitProperties;
  }

  @Autowired
  public void setInstanceIsolationProperties(InstanceIsolationProperties instanceIsolationProperties) {
    this.instanceIsolationProperties = instanceIsolationProperties;
  }

  @Autowired
  public void setRetryProperties(RetryProperties retryProperties) {
    this.retryProperties = retryProperties;
  }

  @Autowired
  public void setEnvironment(Environment environment) {
    this.environment = environment;
  }

  @Autowired
  public void setDynamicValues(Map<String, Object> dynamicValues) {
    this.dynamicValues = dynamicValues;
  }

  public GovernancePropertiesTest() {
  }

  private Map<String, Object> dynamicValues = new HashMap<>();

  private static final float DELTA = 0.0000001f;

  @BeforeEach
  public void setUp() {
    ConfigurableEnvironment configurableEnvironment = (ConfigurableEnvironment) environment;

    if (configurableEnvironment.getPropertySources().contains("testDynamicChange")) {
      configurableEnvironment.getPropertySources().remove("testDynamicChange");
    }

    configurableEnvironment.getPropertySources()
        .addFirst(new EnumerablePropertySource<Map<String, Object>>("testDynamicChange", dynamicValues) {
          @Override
          public Object getProperty(String s) {
            return this.getSource().get(s);
          }

          @Override
          public String[] getPropertyNames() {
            return this.getSource().keySet().toArray(new String[0]);
          }
        });
  }

  @AfterEach
  public void tearDown() {
    Set<String> keys = dynamicValues.keySet();
    keys.forEach(k -> dynamicValues.put(k, null));
    GovernanceEventManager.post(new GovernanceConfigurationChangedEvent(new HashSet<>(dynamicValues.keySet())));
  }

  @Test
  public void test_all_bean_is_loaded() {
    Assertions.assertEquals(5, propertiesList.size());
  }

  @Test
  public void test_match_properties_successfully_loaded() {
    Map<String, TrafficMarker> markers = matchProperties.getParsedEntity();
    Assertions.assertEquals(6, markers.size());
    TrafficMarker demoRateLimiting = markers.get("demo-rateLimiting");
    List<Matcher> matchers = demoRateLimiting.getMatches();
    Assertions.assertEquals(1, matchers.size());
    Matcher matcher = matchers.get(0);
    Assertions.assertEquals("/hello", matcher.getApiPath().get("exact"));

    TrafficMarker demoBulkhead = markers.get("demo-bulkhead");
    matchers = demoBulkhead.getMatches();
    Assertions.assertEquals(2, matchers.size());
    matcher = matchers.get(0);
    Assertions.assertEquals("/bulkhead", matcher.getApiPath().get("exact"));
    Assertions.assertEquals("matchPath", matcher.getName());
  }

  @Test
  public void test_match_properties_delete() {
    Map<String, TrafficMarker> markers = matchProperties.getParsedEntity();
    Assertions.assertEquals(6, markers.size());
    dynamicValues.put("servicecomb.matchGroup.test", "matches:\n"
        + "  - apiPath:\n"
        + "      exact: \"/hello2\"\n"
        + "    name: match0");
    GovernanceEventManager.post(new GovernanceConfigurationChangedEvent(new HashSet<>(dynamicValues.keySet())));
    markers = matchProperties.getParsedEntity();
    Assertions.assertEquals(7, markers.size());
    tearDown();
    markers = matchProperties.getParsedEntity();
    Assertions.assertEquals(6, markers.size());
  }

  @Test
  public void test_match_properties_changed() {
    dynamicValues.put("servicecomb.matchGroup.demo-rateLimiting", "matches:\n"
        + "  - apiPath:\n"
        + "      exact: \"/hello2\"\n"
        + "    name: match0");
    dynamicValues.put("servicecomb.matchGroup.demo-rateLimiting2", "matches:\n"
        + "  - apiPath:\n"
        + "      exact: \"/hello2\"\n"
        + "    name: match0");

    GovernanceEventManager.post(new GovernanceConfigurationChangedEvent(new HashSet<>(dynamicValues.keySet())));

    Map<String, TrafficMarker> markers = matchProperties.getParsedEntity();
    Assertions.assertEquals(7, markers.size());
    TrafficMarker demoRateLimiting = markers.get("demo-rateLimiting");
    List<Matcher> matchers = demoRateLimiting.getMatches();
    Assertions.assertEquals(1, matchers.size());
    Matcher matcher = matchers.get(0);
    Assertions.assertEquals("/hello2", matcher.getApiPath().get("exact"));

    demoRateLimiting = markers.get("demo-rateLimiting2");
    matchers = demoRateLimiting.getMatches();
    Assertions.assertEquals(1, matchers.size());
    matcher = matchers.get(0);
    Assertions.assertEquals("/hello2", matcher.getApiPath().get("exact"));
  }

  @Test
  public void test_bulkhead_properties_changed() {
    dynamicValues.put("servicecomb.bulkhead.demo-bulkhead", "rules:\n"
        + "maxConcurrentCalls: 2\n"
        + "maxWaitDuration: 2000");
    dynamicValues.put("servicecomb.bulkhead.bulkhead1", "rules:\n"
        + "maxConcurrentCalls: 3\n"
        + "maxWaitDuration: 3000");

    GovernanceEventManager.post(new GovernanceConfigurationChangedEvent(new HashSet<>(dynamicValues.keySet())));

    Map<String, BulkheadPolicy> policies = bulkheadProperties.getParsedEntity();
    Assertions.assertEquals(3, policies.size());
    BulkheadPolicy policy = policies.get("demo-bulkhead");
    Assertions.assertEquals(2, policy.getMaxConcurrentCalls());
    Assertions.assertEquals(2000, Duration.parse(policy.getMaxWaitDuration()).toMillis());

    policies = bulkheadProperties.getParsedEntity();
    Assertions.assertEquals(3, policies.size());
    policy = policies.get("bulkhead1");
    Assertions.assertEquals(3, policy.getMaxConcurrentCalls());
    Assertions.assertEquals(3000, Duration.parse(policy.getMaxWaitDuration()).toMillis());
    Assertions.assertEquals("bulkhead1", policy.getName());
  }

  @Test
  public void test_bulkhead_properties_bound() {
    dynamicValues.put("servicecomb.bulkhead.test-bulkhead1", "rules:\n"
        + "maxConcurrentCalls: 0\n"
        + "maxWaitDuration: 2000");
    dynamicValues.put("servicecomb.bulkhead.test-bulkhead2", "rules:\n"
        + "maxConcurrentCalls: 1000\n"
        + "maxWaitDuration: 0");
    dynamicValues.put("servicecomb.bulkhead.test-bulkhead3", "rules:\n"
        + "maxConcurrentCalls: 0\n"
        + "maxWaitDuration: 2S");

    GovernanceEventManager.post(new GovernanceConfigurationChangedEvent(new HashSet<>(dynamicValues.keySet())));

    Map<String, BulkheadPolicy> policies = bulkheadProperties.getParsedEntity();
    Assertions.assertEquals(5, policies.size());
    BulkheadPolicy policy = policies.get("test-bulkhead1");
    Assertions.assertEquals(0, policy.getMaxConcurrentCalls());
    Assertions.assertEquals(2000, Duration.parse(policy.getMaxWaitDuration()).toMillis());

    policy = policies.get("test-bulkhead2");
    Assertions.assertEquals(1000, policy.getMaxConcurrentCalls());
    Assertions.assertEquals(0, Duration.parse(policy.getMaxWaitDuration()).toMillis());
    Assertions.assertEquals("test-bulkhead2", policy.getName());

    policy = policies.get("test-bulkhead3");
    Assertions.assertEquals(0, policy.getMaxConcurrentCalls());
    Assertions.assertEquals(2000, Duration.parse(policy.getMaxWaitDuration()).toMillis());
    Assertions.assertEquals("test-bulkhead3", policy.getName());
  }

  @Test
  public void test_bulkhead_properties_successfully_loaded() {
    Map<String, BulkheadPolicy> policies = bulkheadProperties.getParsedEntity();
    Assertions.assertEquals(2, policies.size());
    BulkheadPolicy policy = policies.get("demo-bulkhead");
    Assertions.assertEquals(1, policy.getMaxConcurrentCalls());
    Assertions.assertEquals(3000, Duration.parse(policy.getMaxWaitDuration()).toMillis());
  }

  @Test
  public void test_circuit_breaker_properties_successfully_loaded() {
    Map<String, CircuitBreakerPolicy> policies = circuitBreakerProperties.getParsedEntity();
    Assertions.assertEquals(1, policies.size());
    CircuitBreakerPolicy policy = policies.get("demo-circuitBreaker");
    Assertions.assertEquals(2, policy.getMinimumNumberOfCalls());
    Assertions.assertEquals("2", policy.getSlidingWindowSize());
  }

  @Test
  public void test_circuit_breaker_properties_Of_windows_size() {
    dynamicValues.put("servicecomb.circuitBreaker.name1", "rules:\n"
        + "slidingWindowType: count\n"
        + "slidingWindowSize: 2");
    dynamicValues.put("servicecomb.circuitBreaker.name2", "rules:\n"
        + "slidingWindowType: time\n"
        + "slidingWindowSize: 2");
    dynamicValues.put("servicecomb.circuitBreaker.name3", "rules:\n"
        + "slidingWindowType: test\n"
        + "slidingWindowSize: 1M");

    GovernanceEventManager.post(new GovernanceConfigurationChangedEvent(new HashSet<>(dynamicValues.keySet())));

    Map<String, CircuitBreakerPolicy> policies = circuitBreakerProperties.getParsedEntity();
    Assertions.assertEquals(4, policies.size());
    CircuitBreakerPolicy policy = policies.get("name1");
    Assertions.assertEquals("count", policy.getSlidingWindowType());
    Assertions.assertEquals("2", policy.getSlidingWindowSize());

    policy = policies.get("name2");
    Assertions.assertEquals("time", policy.getSlidingWindowType());
    Assertions.assertEquals("2", policy.getSlidingWindowSize());

    policy = policies.get("name3");
    Assertions.assertEquals("60", policy.getSlidingWindowSize());
  }

  @Test
  public void test_circuit_breaker_properties_Of_type() {
    dynamicValues.put("servicecomb.circuitBreaker.type1", "rules:\n"
        + "failureRateThreshold: 20\n"
        + "slowCallRateThreshold: 100");
    dynamicValues.put("servicecomb.circuitBreaker.type2", "rules:\n"
        + "failureRateThreshold: 20.33\n"
        + "slowCallRateThreshold: 0.01");

    GovernanceEventManager.post(new GovernanceConfigurationChangedEvent(new HashSet<>(dynamicValues.keySet())));

    Map<String, CircuitBreakerPolicy> policies = circuitBreakerProperties.getParsedEntity();
    CircuitBreakerPolicy policy = policies.get("type1");
    Assertions.assertEquals(20.0f, policy.getFailureRateThreshold(), DELTA);
    Assertions.assertEquals(100.0f, policy.getSlowCallRateThreshold(), DELTA);

    policy = policies.get("type2");
    Assertions.assertEquals(20.33f, policy.getFailureRateThreshold(), DELTA);
    Assertions.assertEquals(0.01f, policy.getSlowCallRateThreshold(), DELTA);
  }

  @Test
  public void test_rate_limit_properties_successfully_loaded() {
    Map<String, RateLimitingPolicy> policies = rateLimitProperties.getParsedEntity();
    Assertions.assertEquals(2, policies.size());
    RateLimitingPolicy policy = policies.get("demo-rateLimiting");
    Assertions.assertEquals(1, policy.getRate());
  }

  @Test
  public void test_retry_properties_successfully_loaded() {
    Map<String, RetryPolicy> policies = retryProperties.getParsedEntity();
    Assertions.assertEquals(1, policies.size());
    RetryPolicy policy = policies.get("demo-retry");
    Assertions.assertEquals(3, policy.getMaxAttempts());
  }


  @Test
  public void test_properties_changed_to_duration() {
    dynamicValues.put("servicecomb.bulkhead.test1", "rules:\n"
        + "maxConcurrentCalls: 2\n"
        + "maxWaitDuration: 2S");
    dynamicValues.put("servicecomb.bulkhead.test2", "rules:\n"
        + "maxConcurrentCalls: 3\n"
        + "maxWaitDuration: 1M");

    GovernanceEventManager.post(new GovernanceConfigurationChangedEvent(new HashSet<>(dynamicValues.keySet())));

    Map<String, BulkheadPolicy> policies = bulkheadProperties.getParsedEntity();
    Assertions.assertEquals(4, policies.size());
    BulkheadPolicy policy = policies.get("test1");
    Assertions.assertEquals(2000, Duration.parse(policy.getMaxWaitDuration()).toMillis());

    policies = bulkheadProperties.getParsedEntity();
    Assertions.assertEquals(4, policies.size());
    policy = policies.get("test2");
    Assertions.assertEquals(60000, Duration.parse(policy.getMaxWaitDuration()).toMillis());
  }

  @Test
  public void test_instance_isolation_properties_successfully_loaded() {
    Map<String, CircuitBreakerPolicy> policies = instanceIsolationProperties.getParsedEntity();
    Assertions.assertEquals(1, policies.size());
    CircuitBreakerPolicy policy = policies.get("default");
    Assertions.assertEquals(2, policy.getMinimumNumberOfCalls());
    Assertions.assertEquals("2", policy.getSlidingWindowSize());
  }
}
