package com.tencent.qian.webview.prewarm;

import androidx.annotation.NonNull;

import com.tencent.qian.webview.model.PrewarmLevel;

import java.util.HashMap;
import java.util.Map;

/**
 * 单调去重状态（design.md Decision 4），线程安全。
 *
 * <ul>
 *   <li>{@link PrewarmLevel#MINIMAL}：全局只做一次。</li>
 *   <li>{@link PrewarmLevel#LIGHT} / {@link PrewarmLevel#HEAVY}：每 bizType 记录已达最高档；
 *       低于等于已达档则不再执行。</li>
 *   <li>不允许降级重热；仅 manifest version 变化时 {@link #reset()} 整体重置。</li>
 * </ul>
 */
public final class PrewarmDedup {

    private final Map<String, PrewarmLevel> reached = new HashMap<>();
    private boolean minimalDone = false;
    private final Object lock = new Object();

    /** 判断本次 (level, bizType) 是否应执行（未被去重）。 */
    public boolean shouldRun(@NonNull PrewarmLevel level, @NonNull String bizType) {
        synchronized (lock) {
            if (level == PrewarmLevel.MINIMAL) {
                return !minimalDone;
            }
            PrewarmLevel cur = reached.get(bizType);
            if (cur == null) {
                return true;
            }
            return level.ordinal() > cur.ordinal();
        }
    }

    /**
     * 标记 (level, bizType) 已完成，更新已达档（单调不降）。
     *
     * <p>档位增量补做：任意档位的 execute 都会先跑全局 DNS，故完成后<b>一律置
     * {@code minimalDone = true}</b>（含直接调 LIGHT/HEAVY 的情形），避免后续 MINIMAL 重复跑 DNS。
     */
    public void markDone(@NonNull PrewarmLevel level, @NonNull String bizType) {
        synchronized (lock) {
            // 任意档位执行后 DNS 已做过 → 置 minimalDone
            minimalDone = true;
            if (level == PrewarmLevel.MINIMAL) {
                return;
            }
            PrewarmLevel cur = reached.get(bizType);
            if (cur == null || level.ordinal() > cur.ordinal()) {
                reached.put(bizType, level);
            }
        }
    }

    /** 整体重置（manifest version 变化时调用）。 */
    public void reset() {
        synchronized (lock) {
            reached.clear();
            minimalDone = false;
        }
    }
}
