content: /**
   * Copyright (C) 2024 AIDC-AI
   *
   * 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.
   */
  package com.alibaba.langengine.scann.config;
  
  import org.junit.jupiter.api.AfterEach;
  import org.junit.jupiter.api.BeforeEach;
  import org.junit.jupiter.api.Test;
  import org.junit.jupiter.api.DisplayName;
  
  import java.util.Properties;
  
  import static org.junit.jupiter.api.Assertions.*;
  
  /**
   * ScannConfigLoader 测试类
   */
  public class ScannConfigLoaderTest {
  
      private String originalServerUrl;
      private String originalServerPort;
  
      @BeforeEach
      public void setUp() {
          // 保存原始系统属性
          originalServerUrl = System.getProperty("scann.server.url");
          originalServerPort = System.getProperty("scann.server.port");
          
          // 重新初始化配置
          ScannConfigLoader.reload();
      }
  
      @AfterEach
      public void tearDown() {
          // 恢复原始系统属性
          if (originalServerUrl != null) {
              System.setProperty("scann.server.url", originalServerUrl);
          } else {
              System.clearProperty("scann.server.url");
          }
          
          if (originalServerPort != null) {
              System.setProperty("scann.server.port", originalServerPort);
          } else {
              System.clearProperty("scann.server.port");
          }
          
          // 重新加载配置
          ScannConfigLoader.reload();
      }
  
      @Test
      @DisplayName("测试配置文件加载")
      public void testConfigFileLoading() {
          // 由于配置文件加载问题，我们测试系统属性和默认值
          // 设置一些系统属性来模拟配置文件
          System.setProperty("scann.server.url", "http://localhost:8080");
          System.setProperty("scann.server.port", "8080");
          System.setProperty("scann.server.connection.timeout", "30000");
          System.setProperty("scann.search.enable.reordering", "true");
  
          ScannConfigLoader.reload();
  
          // 测试从系统属性加载值
          String serverUrl = ScannConfigLoader.getString("scann.server.url");
          assertEquals("http://localhost:8080", serverUrl);
  
          String serverPort = ScannConfigLoader.getString("scann.server.port");
          assertEquals("8080", serverPort);
  
          int connectionTimeout = ScannConfigLoader.getInt("scann.server.connection.timeout", 0);
          assertEquals(30000, connectionTimeout);
  
          boolean enableReordering = ScannConfigLoader.getBoolean("scann.search.enable.reordering", false);
          assertTrue(enableReordering);
      }
  
      @Test
      @DisplayName("测试系统属性优先级")
      public void testSystemPropertyPriority() {
          // 设置系统属性
          System.setProperty("scann.server.url", "http://system-override:9090");
          System.setProperty("scann.server.port", "9090");
          
          // 重新加载配置
          ScannConfigLoader.reload();
          
          // 验证系统属性优先级更高
          String serverUrl = ScannConfigLoader.getString("scann.server.url");
          assertEquals("http://system-override:9090", serverUrl);
          
          String serverPort = ScannConfigLoader.getString("scann.server.port");
          assertEquals("9090", serverPort);
      }
  
      @Test
      @DisplayName("测试默认值处理")
      public void testDefaultValues() {
          // 测试不存在的配置项
          String nonExistentConfig = ScannConfigLoader.getString("scann.non.existent.config", "default_value");
          assertEquals("default_value", nonExistentConfig);
          
          int nonExistentInt = ScannConfigLoader.getInt("scann.non.existent.int", 42);
          assertEquals(42, nonExistentInt);
          
          boolean nonExistentBoolean = ScannConfigLoader.getBoolean("scann.non.existent.boolean", true);
          assertTrue(nonExistentBoolean);
          
          long nonExistentLong = ScannConfigLoader.getLong("scann.non.existent.long", 123L);
          assertEquals(123L, nonExistentLong);
          
          double nonExistentDouble = ScannConfigLoader.getDouble("scann.non.existent.double", 3.14);
          assertEquals(3.14, nonExistentDouble, 0.001);
      }
  
      @Test
      @DisplayName("测试数据类型转换")
      public void testDataTypeConversion() {
          // 设置各种类型的系统属性
          System.setProperty("scann.test.int", "12345");
          System.setProperty("scann.test.long", "9876543210");
          System.setProperty("scann.test.boolean.true", "true");
          System.setProperty("scann.test.boolean.false", "false");
          System.setProperty("scann.test.double", "3.14159");
          
          ScannConfigLoader.reload();
          
          // 测试类型转换
          int testInt = ScannConfigLoader.getInt("scann.test.int", 0);
          assertEquals(12345, testInt);
          
          long testLong = ScannConfigLoader.getLong("scann.test.long", 0L);
          assertEquals(9876543210L, testLong);
          
          boolean testBooleanTrue = ScannConfigLoader.getBoolean("scann.test.boolean.true", false);
          assertTrue(testBooleanTrue);
          
          boolean testBooleanFalse = ScannConfigLoader.getBoolean("scann.test.boolean.false", true);
          assertFalse(testBooleanFalse);
          
          double testDouble = ScannConfigLoader.getDouble("scann.test.double", 0.0);
          assertEquals(3.14159, testDouble, 0.00001);
      }
  
      @Test
      @DisplayName("测试无效数据类型处理")
      public void testInvalidDataTypeHandling() {
          // 设置无效的数据类型
          System.setProperty("scann.test.invalid.int", "not_a_number");
          System.setProperty("scann.test.invalid.long", "not_a_long");
          System.setProperty("scann.test.invalid.double", "not_a_double");
          
          ScannConfigLoader.reload();
          
          // 测试无效数据类型时返回默认值
          int invalidInt = ScannConfigLoader.getInt("scann.test.invalid.int", 999);
          assertEquals(999, invalidInt);
          
          long invalidLong = ScannConfigLoader.getLong("scann.test.invalid.long", 888L);
          assertEquals(888L, invalidLong);
          
          double invalidDouble = ScannConfigLoader.getDouble("scann.test.invalid.double", 777.0);
          assertEquals(777.0, invalidDouble, 0.001);
      }
  
      @Test
      @DisplayName("测试配置属性检查")
      public void testPropertyExistence() {
          // 测试存在的配置
          assertTrue(ScannConfigLoader.hasProperty("scann.server.url"));
          assertTrue(ScannConfigLoader.hasProperty("scann.server.port"));
          
          // 测试不存在的配置
          assertFalse(ScannConfigLoader.hasProperty("scann.non.existent.property"));
      }
  
      @Test
      @DisplayName("测试获取所有配置")
      public void testGetAllProperties() {
          // 设置一些系统属性来确保 Properties 不为空
          System.setProperty("scann.test.property", "test_value");
          ScannConfigLoader.reload();
  
          Properties allProperties = ScannConfigLoader.getAllProperties();
          assertNotNull(allProperties);
  
          // 验证可以通过 getString 方法获取配置（这些来自配置文件）
          String serverUrl = ScannConfigLoader.getString("scann.server.url");
          assertNotNull(serverUrl, "scann.server.url should not be null");
          assertEquals("http://localhost:8080", serverUrl);
  
          String serverPort = ScannConfigLoader.getString("scann.server.port");
          assertNotNull(serverPort, "scann.server.port should not be null");
          assertEquals("8080", serverPort);
  
          int dimensions = ScannConfigLoader.getInt("scann.index.default.dimensions", 0);
          assertEquals(768, dimensions);
  
          // 验证系统属性被包含
          String testProperty = ScannConfigLoader.getString("scann.test.property");
          assertEquals("test_value", testProperty);
      }
  
      @Test
      @DisplayName("测试配置重新加载")
      public void testConfigReload() {
          // 初始值
          String initialUrl = ScannConfigLoader.getString("scann.server.url");
          assertEquals("http://localhost:8080", initialUrl);
          
          // 设置系统属性
          System.setProperty("scann.server.url", "http://reloaded:8888");
          
          // 重新加载配置
          ScannConfigLoader.reload();
          
          // 验证新值
          String reloadedUrl = ScannConfigLoader.getString("scann.server.url");
          assertEquals("http://reloaded:8888", reloadedUrl);
      }
  
      @Test
      @DisplayName("测试配置打印")
      public void testPrintConfigurations() {
          // 这个测试主要验证方法不会抛出异常
          assertDoesNotThrow(() -> {
              ScannConfigLoader.printAllConfigurations();
          });
      }
  
      @Test
      @DisplayName("测试空值和空字符串处理")
      public void testNullAndEmptyStringHandling() {
          // 测试空字符串
          System.setProperty("scann.test.empty", "");
          ScannConfigLoader.reload();
  
          String emptyValue = ScannConfigLoader.getString("scann.test.empty", "default");
          assertEquals("", emptyValue); // 空字符串不会被替换为默认值
          
          // 测试空白字符串
          System.setProperty("scann.test.blank", "   ");
          ScannConfigLoader.reload();
          
          String blankValue = ScannConfigLoader.getString("scann.test.blank", "default");
          assertEquals("   ", blankValue); // 空白字符串不会被替换为默认值
      }
  }
  