package me.qwq.doghouse.pojo.bo;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import jakarta.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;

import lombok.AccessLevel;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import me.qwq.doghouse.annotation.StaticAttribute;
import me.qwq.doghouse.entity.Post;
import me.qwq.doghouse.interfaces.IPostPassMess;
import me.qwq.doghouse.util.Cryptos;
import me.qwq.doghouse.util.SessionUtils;

/**
 * 文章密码存储罐
 * @author Doghole
 *
 */
@Data
@Accessors(chain=true)
@StaticAttribute
public class PostPassJar implements Serializable {
    
    private static final long serialVersionUID = -3135412411890236084L;
    
    @Getter(AccessLevel.PRIVATE) @Setter(AccessLevel.PRIVATE)
    Map<Long, String> postPassMap = new HashMap<>();

    /**
     * 添加一条 Post 和对应的 Pass 记录
     * @param post
     * @param pass
     * @return
     */
    private PostPassJar add(Post post, String pass) {
        postPassMap.put(post.getPostId(), pass);
        return this;
    }
    
    private PostPassJar del(IPostPassMess<?> postMess) {
        postPassMap.remove(postMess.getPostId());
        return this;
    }
    
    /**
     * 是否验证成功
     * @param post
     * @param givenPassword
     * @return
     */
    private Boolean valid(IPostPassMess<?> post) {
        if (post == null || post.getPostId() == null || 
                !postPassMap.containsKey(post.getPostId())) {
            return false;
        }
        if (!postPassMap.containsKey(post.getPostId())) {
            return false;
        }
        String givenPassword = Cryptos.sha3(post.getPassword(), 224);
        Boolean valid = postPassMap.get(post.getPostId()).equals(givenPassword);
        if (valid) {
            post.setPassword(null);
        }
        return valid;
    }
    
    /**
     * 将指定的 Post 和 Pass 关系加入 session
     * @param session
     * @param post
     * @param userInputPass
     */
    public static void addToSession(HttpSession session, Post post, String userInputPass) {
        PostPassJar jar = (PostPassJar) session.getAttribute(SessionUtils.POST_PASS_JAR);
        if (jar == null) {
            jar = new PostPassJar();
        }
        jar.add(post, userInputPass);
        session.setAttribute(SessionUtils.POST_PASS_JAR, jar);
    }
    
    /**
     * 从 Session 验证并去除可能的密码
     * @param session
     * @param post
     * @return
     */
    public static Boolean validFromSession(HttpSession session, IPostPassMess<?> post) {
        if (StringUtils.isEmpty(post.getPassword())) {
            return true;
        }
        if (session == null) return false;
        
        if (SessionUtils.isLogin(session)) return true;
        
        PostPassJar jar = (PostPassJar) session.getAttribute(SessionUtils.POST_PASS_JAR);
        if (jar == null) {
            return false;
        }
        return jar.valid(post);
    }
    
    public static void removeFromSession(HttpSession session, IPostPassMess<?> postMess) {
        PostPassJar jar = (PostPassJar) session.getAttribute(SessionUtils.POST_PASS_JAR);
        if (jar != null) {
            jar.del(postMess);
        }
        session.setAttribute(SessionUtils.POST_PASS_JAR, jar);
    }
    
    public static Boolean containsInSession(HttpSession session, IPostPassMess<?> postMess) {
        if (postMess == null) return false;
        PostPassJar jar = (PostPassJar) session.getAttribute(SessionUtils.POST_PASS_JAR);
        if (jar == null) {
            return false;
        }
        return jar.postPassMap.containsKey(postMess.getPostId());
    }

}
