 package com.qqchen.deploy.backend.framework.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;

import java.lang.reflect.Field;

@Slf4j
public class ReflectionUtils {

    /**
     * 设置字段值
     *
     * @param fieldName 字段名
     * @param target 目标对象
     * @param value 值
     */
    public static void setField(String fieldName, Object target, Object value) {
        Assert.notNull(fieldName, "Field name must not be null");
        Assert.notNull(target, "Target object must not be null");

        try {
            Field field = findField(target.getClass(), fieldName);
            if (field == null) {
                throw new IllegalArgumentException(
                    "Could not find field [" + fieldName + "] on target [" + target.getClass().getName() + "]");
            }

            makeAccessible(field);
            field.set(target, value);
        } catch (Exception e) {
            log.error("Failed to set field [{}] on target [{}]", fieldName, target.getClass().getName(), e);
            throw new IllegalStateException("Failed to set field: " + fieldName, e);
        }
    }

    /**
     * 获取字段值
     *
     * @param fieldName 字段名
     * @param target 目标对象
     * @return 字段值
     */
    public static Object getField(String fieldName, Object target) {
        Assert.notNull(fieldName, "Field name must not be null");
        Assert.notNull(target, "Target object must not be null");

        try {
            Field field = findField(target.getClass(), fieldName);
            if (field == null) {
                throw new IllegalArgumentException(
                    "Could not find field [" + fieldName + "] on target [" + target.getClass().getName() + "]");
            }

            makeAccessible(field);
            return field.get(target);
        } catch (Exception e) {
            log.error("Failed to get field [{}] on target [{}]", fieldName, target.getClass().getName(), e);
            throw new IllegalStateException("Failed to get field: " + fieldName, e);
        }
    }

    /**
     * 查找字段（包括父类）
     */
    private static Field findField(Class<?> clazz, String fieldName) {
        Class<?> searchType = clazz;
        while (searchType != null && !Object.class.equals(searchType)) {
            try {
                return searchType.getDeclaredField(fieldName);
            } catch (NoSuchFieldException e) {
                searchType = searchType.getSuperclass();
            }
        }
        return null;
    }

    /**
     * 使字段可访问
     */
    private static void makeAccessible(Field field) {
        if (!field.isAccessible()) {
            field.setAccessible(true);
        }
    }
}