using System;
using System.Reflection;


namespace UVC.Attribute
{
    /// <summary>
    /// enum의 string 값을 가져오기 위한 Attribute입니다.
    /// enum 값에 문자열을 연결하여 표시 이름, API 매핑 등 다양한 용도로 활용할 수 있습니다.
    /// </summary>
    /// <remarks>
    /// 사용 예제:
    /// <code>
    /// public enum Test {
    ///    [StringValue("a")]
    ///    Foo,
    ///    [StringValue("b")]
    ///    Something
    /// }
    /// 
    /// string value = Test.Foo.GetStringValue(); // "a" 반환
    /// </code>
    /// 출처: https://weblogs.asp.net/stefansedich/enum-with-string-values-in-c
    /// </remarks>
    public class StringValueAttribute : System.Attribute
    {
        #region Properties

        /// <summary>
        /// enum 값에 연결된 문자열 값을 저장합니다.
        /// </summary>
        public string StringValue { get; protected set; }

        #endregion

        #region Constructor

        /// <summary>
        /// StringValue Attribute를 초기화하는 생성자입니다.
        /// </summary>
        /// <param name="value">enum 값과 연결할 문자열</param>
        /// <example>
        /// <code>
        /// public enum UserType {
        ///    [StringValue("관리자")]
        ///    Admin,
        ///    [StringValue("일반 사용자")]
        ///    Normal
        /// }
        /// </code>
        /// </example>
        public StringValueAttribute(string value)
        {
            this.StringValue = value;
        }

        #endregion
    }

    
    public static class StringValueEx
    {
        /// <summary>
        /// enum 값에 연결된 StringValue 속성의 문자열 값을 가져옵니다.
        /// </summary>
        /// <param name="value">문자열 값을 가져올 enum 값</param>
        /// <returns>연결된 문자열 값이 있으면 해당 값을, 없으면 null을 반환합니다.</returns>
        /// <example>
        /// <code>
        /// public enum ApiEndpoint {
        ///     [StringValue("/api/users")]
        ///     Users,
        ///     [StringValue("/api/products")]
        ///     Products
        /// }
        /// 
        /// // 사용 예:
        /// string endpoint = ApiEndpoint.Users.GetStringValue(); // "/api/users" 반환
        /// 
        /// // 실제 API 호출 시 활용:
        /// var url = baseUrl + ApiEndpoint.Products.GetStringValue();
        /// HttpClient.Get(url);
        /// </code>
        /// </example>
        public static string GetStringValue(this Enum value)
        {
            // 타입 정보 가져오기
            Type type = value.GetType();

            // 현재 enum 값에 대한 필드 정보 가져오기
            FieldInfo fieldInfo = type.GetField(value.ToString());

            // StringValue 특성 배열 가져오기
            StringValueAttribute[] attribs = fieldInfo.GetCustomAttributes(
                typeof(StringValueAttribute), false) as StringValueAttribute[];

            // 일치하는 것이 있으면 첫 번째 특성의 문자열 값 반환
            return attribs.Length > 0 ? attribs[0].StringValue : null;
        }
    }
}

