package com.apobates.forum.strategy.exposure.config.impl;

import com.apobates.forum.core.entity.Topic;
import com.apobates.forum.core.entity.TopicConfig;
import com.apobates.forum.member.entity.Member;
import com.apobates.forum.strategy.StrategyMode;
import com.apobates.forum.strategy.exception.CulpritorIllegalStatusException;
import com.apobates.forum.strategy.exception.ReadStrategyException;
import com.apobates.forum.strategy.exception.StrategyException;
import com.apobates.forum.strategy.exception.WriteStrategyException;
import com.apobates.forum.strategy.exposure.config.AbstractConfigStrategy;
import com.apobates.forum.strategy.exposure.config.ComplexConfigStrategyExector;
import com.apobates.forum.utils.lang.TriPredicate;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;

/**
 * 话题配置文件检测策略
 * 
 * @author xiaofanku
 * @since 20200806
 */
public final class TopicConfigStrategy extends AbstractConfigStrategy<Topic, TopicConfig>{
    public final static BiFunction<Topic, Member, TopicConfigStrategy.Builer> BUILDER = (entity, member)->new TopicConfigStrategy.Builer(entity, member);
    
    public final static class Builer{
        private final Topic topic;
        private final Member member;
        
        public Builer(Topic topic, Member member) {
            this.topic = topic;
            this.member = member;
        }
        
        public ComplexConfigStrategyExector<Topic,TopicConfig> initial(TopicConfig entityConfig, StrategyMode mode)throws StrategyException{
            return new TopicConfigStrategy().initial(entityConfig, topic, mode, member);
        }
    }
    
    @Override
    protected BiPredicate<Topic, StrategyMode> checkEntity() { //B: config中的话题检查项目{checkSelf}
        return (Topic entity, StrategyMode currentMode)->{
            if (StrategyMode.WRITE == currentMode) {
                if (!entity.isNormal()) { 
                    throw new WriteStrategyException("话题当前的状态禁止写入操作");
                }
            }
            return true;
        };
    }
    
    @Override
    protected TriPredicate<TopicConfig, Member, StrategyMode> checkCulpritor() { //D: config中的会员检查项目{checkCulpritor()}
        return (TopicConfig entityConfig, Member currentMember, StrategyMode currentMode)->{
            return checkCulpritorStatus(currentMember, currentMode) && checkCulpritorRG(entityConfig, currentMember, currentMode);
        };
    }
    /**
     * 操作者状态检查
     * @param culpritor 
     * @param mode 策略的模式
     * @return
     * @throws StrategyException
     */
    private static boolean checkCulpritorStatus(Member culpritor, StrategyMode mode) throws StrategyException {
        if (StrategyMode.WRITE == mode) {
            if (culpritor.getId() <= 0) {
                throw new CulpritorIllegalStatusException("匿名用户禁止回复");
            }
            if (culpritor.getStatus().getSymbol() < 3) {
                throw new CulpritorIllegalStatusException("您当前状态不具备回复权限");
            }
        }
        return true;
    }
    /**
     * 话题配置文件检查
     *
     * @param entityConfig 话题配置文件
     * @param culpritor 
     * @param mode 策略的模式
     * @return
     * @throws StrategyException
     */
    private static boolean checkCulpritorRG(TopicConfig entityConfig, Member culpritor, StrategyMode mode) throws StrategyException {
        if (StrategyMode.READ == mode) {
            return checkCulpritorRGForReadMode(entityConfig, culpritor); 
        }
        if (StrategyMode.WRITE == mode) {
            return checkCulpritorRGForWriteMode(entityConfig, culpritor); 
        }
        return true;
    }
    /**
     *
     * @param entityConfig 话题配置文件
     * @param culpritor 
     * @return
     */
    private static boolean checkCulpritorRGForReadMode(TopicConfig entityConfig, Member culpritor) throws StrategyException {
        //组
        if (culpritor.getMgroup().getSymbol() < entityConfig.getReadLowMemberGroup().getSymbol()) {
            throw new ReadStrategyException("您当前的组不满足话题阅读要求");
        }
        //角色
        if (culpritor.getMrole().getSymbol() < entityConfig.getReadLowMemberRole().getSymbol()) {
            throw new ReadStrategyException("您当前的角色不满足话题阅读要求");
        }
        //等级积分要求
        //ETC
        return true;
    }
    
    private static boolean checkCulpritorRGForWriteMode(TopicConfig entityConfig, Member culpritor) throws StrategyException {
        //配置文件是否开启了禁止回复
        if (!entityConfig.isReply()) {
            throw new WriteStrategyException("话题配置文件关闭了回复功能");
        }
        //组
        if (culpritor.getMgroup().getSymbol() < entityConfig.getWriteLowMemberGroup().getSymbol()) {
            throw new WriteStrategyException("您当前的组不满足话题写入要求");
        }
        //角色
        if (culpritor.getMrole().getSymbol() < entityConfig.getWriteLowMemberRole().getSymbol()) {
            throw new WriteStrategyException("您当前的角色不满足话题写入要求");
        }
        //是否跳过版主的积分和等级检查
        //ETC
        return true;
    }
}