package com.malk.pro.tenant;

/**
 * 租户上下文（ThreadLocal）
 *
 * <p>规则（capability: multi-tenant-runtime）：</p>
 * <ul>
 *   <li>请求入口 {@link TenantInterceptor} 写入</li>
 *   <li>finally 块 / {@code afterCompletion} 清理，防止线程池复用污染</li>
 *   <li>异步线程切换用 {@link #propagate(TenantProfile, Runnable)}</li>
 * </ul>
 */
public final class TenantContext {

    private static final ThreadLocal<TenantProfile> HOLDER = new ThreadLocal<>();

    private TenantContext() {
    }

    public static void set(TenantProfile profile) {
        HOLDER.set(profile);
    }

    public static TenantProfile current() {
        return HOLDER.get();
    }

    public static String currentTenantId() {
        TenantProfile p = HOLDER.get();
        return p == null ? null : p.getTenantId();
    }

    public static void clear() {
        HOLDER.remove();
    }

    /**
     * 在指定 TenantProfile 下执行 runnable，执行结束恢复原 context。
     *
     * <p>手动切换线程时使用：</p>
     * <pre>
     * TenantProfile ctx = TenantContext.current();
     * CompletableFuture.runAsync(() -&gt; TenantContext.propagate(ctx, () -&gt; {
     *     // 这里 TenantContext.current() 可用
     * }), executor);
     * </pre>
     */
    public static void propagate(TenantProfile target, Runnable runnable) {
        TenantProfile prev = HOLDER.get();
        HOLDER.set(target);
        try {
            runnable.run();
        } finally {
            if (prev == null) {
                HOLDER.remove();
            } else {
                HOLDER.set(prev);
            }
        }
    }
}
