using System;
using System.Reflection;
using System.Text;
using Xunit;
using CncModels.Enum;

namespace CncModels.Tests
{
    /// <summary>
    /// 测试所有 CncModels.Enum 下的字符串常量，确保值与命名约定一致。
    /// 约定：字段名转换为 snake_case 小写字符串后应当与常量值一致。
    /// 例如 AlertType.CollectFail 应为 "collect_fail"。
    /// </summary>
    public class EnumTests
    {
        /// <summary>
        /// 遍历除 LogLevel 外的所有枚举类，验证 snake_case 命名约定
        /// 覆盖场景：AlertType/CollectStatus/DataStatus/CardType/DataType/MatchBy/SegmentCloseReason/CollectorServiceStatus/ValueType
        /// </summary>
        [Fact]
        public void SnakeCaseEnums_ShouldMatchFieldNames()
        {
            Type[] snakeCaseEnums = new Type[]
            {
                typeof(AlertType),
                typeof(CollectStatus),
                typeof(DataStatus),
                typeof(CardType),
                typeof(DataType),
                typeof(MatchBy),
                typeof(SegmentCloseReason),
                typeof(CollectorServiceStatus),
                typeof(CncModels.Enum.ValueType)
            };

            foreach (var t in snakeCaseEnums)
            {
                var fields = t.GetFields(BindingFlags.Public | BindingFlags.Static);
                Assert.True(fields.Length > 0, $"类型 {t.Name} 不包含公共静态字段。");
                foreach (var f in fields)
                {
                    if (f.FieldType != typeof(string)) continue;
                    string value = (string)f.GetValue(null);
                    string expected = ToSnakeCase(f.Name);
                    Assert.Equal(expected, value);
                }
            }
        }

        /// <summary>
        /// 验证 LogLevel 枚举值为大写（数据库中 log_level 存储为大写）
        /// 覆盖场景：DEBUG/INFO/WARN/ERROR 全部值
        /// </summary>
        [Fact]
        public void LogLevel_ShouldBeUppercase()
        {
            Assert.Equal("DEBUG", LogLevel.Debug);
            Assert.Equal("INFO", LogLevel.Info);
            Assert.Equal("WARN", LogLevel.Warn);
            Assert.Equal("ERROR", LogLevel.Error);
        }

        private string ToSnakeCase(string input)
        {
            if (string.IsNullOrEmpty(input)) return input;
            var sb = new StringBuilder();
            for (int i = 0; i < input.Length; i++)
            {
                char c = input[i];
                if (char.IsUpper(c))
                {
                    if (i > 0) sb.Append('_');
                    sb.Append(char.ToLowerInvariant(c));
                }
                else
                {
                    sb.Append(c);
                }
            }
            return sb.ToString();
        }
    }
}
