package com.apobates.forum.core.entity.proxy;

import com.apobates.forum.core.entity.Board;
import com.apobates.forum.core.entity.BoardConfig;
import com.apobates.forum.core.entity.BoardGroup;
import com.apobates.forum.core.entity.BoardModerator;
import com.apobates.forum.core.entity.BoardStats;
import com.apobates.forum.utils.Commons;
import com.apobates.forum.utils.lang.ForumReplicable;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * @author xiaofanku
 * @since 20200513
 */
public final class BoardReplica extends Board implements ActiveDirectoryConnector<BoardReplica>, ForumReplicable<Board,BoardReplica>{
    //版主容器
    private List<BoardModerator> moderatores;//策略模式需要
    private BoardConfig configure; //策略模式需要
    private BoardStats stats;
    private BoardGroupReplica volumes;
    private final static Pattern BOARD_URL_PARSE = Pattern.compile("/board/(.*).xhtml");
    private final static Logger logger = LoggerFactory.getLogger(BoardReplica.class);
    public static Function<Board, BoardReplica> copyBoard = (Board board) ->{
        return ForumReplicable.replica(board, BoardReplica.class).orElseGet(BoardReplica::new);
    };
    
    public BoardReplica() {
        super();
    }
    
    public static Optional<BoardReplica> of(String connectValue){
        try{
            return new BoardReplica().toConnector(connectValue);
        }catch(IllegalStateException e){
            return Optional.empty();
        }
    }
    public static Optional<BoardReplica> of(String requestRefString, String siteDomain) {
        if (requestRefString == null || !requestRefString.startsWith(siteDomain)) { // 只允许本站连接
            return Optional.empty();
        }
        //
        Matcher m = BOARD_URL_PARSE.matcher(requestRefString);
        String connectValue = null;
        if (m.find()) {
            connectValue = m.group(1);
        }
        try {
            if (connectValue != null && connectValue.contains("volumes/")) { //从版块组->版块
                connectValue = connectValue.replace("volumes/", "");
            }
        } catch (NullPointerException e) {}
        return of(connectValue);
    }
    //
    public List<BoardModerator> getModeratores() {
        return moderatores;
    }
    public void setModeratores(List<BoardModerator> moderatores){
        this.moderatores = moderatores;
    }
    //
    public BoardConfig getConfigure() {
        return configure;
    }
    public void setConfigure(BoardConfig config){
        this.configure = config;
    }
    //
    public BoardStats getStats() {
        return stats;
    }
    public void setStats(BoardStats stats){
        this.stats = stats;
    }
    //
    public BoardGroupReplica getVolumes() {
        return volumes;
    }
    public void copyVolumes(BoardGroup boardGroup){
        this.volumes = Optional.ofNullable(boardGroup).map(BoardGroupReplica.copyBoardGroup).orElse(null);
    }
    public void setVolumes(BoardGroupReplica boardGroup){
        this.volumes = boardGroup;
    }
    @Override
    public String getConnect() {
        return getId()+"-"+getVolumesId();
    }
    
    @Override
    public Optional<BoardReplica> toConnector(String connectValue) throws IllegalStateException {
        String[] params = {};
        try {
            params = connectValue.split("-");
        } catch (NullPointerException | PatternSyntaxException e) {
            throw new IllegalStateException("构造版块的ActiveDirectoryConnector实例参数不合法");
        }
        if (params.length == 0) {
            throw new IllegalStateException("构造版块的ActiveDirectoryConnector实例失败");
        }
        //话题: x-x-x
        //版块: x-x
        //版块组: x
        if (params.length == 1) {
            BoardReplica board = new BoardReplica();
            board.setVolumesId(Commons.stringToInteger(params[0], -1));
            return Optional.of(board);
        }
        if (params.length == 2) {
            BoardReplica board = new BoardReplica();
            board.setId(Commons.stringToLong(params[0], 0L));
            board.setVolumesId(Commons.stringToInteger(params[1], -1));
            return Optional.of(board);
        }
        if (params.length == 3) {
            BoardReplica board = new BoardReplica();
            board.setId(Commons.stringToLong(params[1], 0L));
            board.setVolumesId(Commons.stringToInteger(params[2], -1));
            return Optional.of(board);
        }
        return Optional.empty();
    }
    public static String generateConnectString(long boardId, int boardGroupId){
        BoardReplica br = new BoardReplica();
        br.setId(boardId);
        br.setVolumesId(boardGroupId);
        
        return br.getConnect();
    }
}