package net.northking.cctp.element.validation;

import net.northking.cctp.element.core.IExecuteContext;
import net.northking.cctp.element.core.Library;
import net.northking.cctp.element.core.exception.KeywordNotFoundException;
import net.northking.cctp.element.core.keyword.KeywordArgument;
import net.northking.cctp.element.core.keyword.KeywordInfo;
import net.northking.cctp.element.core.support.ThreadLevelCache;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 组件库规范检查
 *
 * @author fengxiang.zhang
 * @since 1.0
 */
public class Constraint {

    private static Logger logger = LoggerFactory.getLogger(Constraint.class);
    private static Pattern VERSION_PATTERN = Pattern.compile("[0-9]+\\.[0-9]{1,2}(\\.[0-9]{1,3})?");

    /**
     * 组件库版本号格式校验
     */
    public static void version(String version) {
        Matcher matcher = VERSION_PATTERN.matcher(version);
        if (!matcher.matches()) {
            throw new ViolateComponentStandardsException(String.format(
                    "Version number [%s] does not match the regular [0-9]+\\.[0-9]{1,2}(\\.[0-9]{1,3})?", version));
        }
    }

    public static void hasText(CharSequence cs, String message) {
        if (StringUtils.isBlank(cs)) {
            throw new ViolateComponentStandardsException(message);
        }
    }

    public static void isEmpty(Object obj, String message) {
        if (obj==null) {
            throw new ViolateComponentStandardsException(message);
        }
    }

    /**
     * 植入组件库编写标准校验规则
     *
     * @param library
     * @return
     */
    public static Library wrap(Library library) {
        if (library == null) {
            return null;
        }
        Library wrapLibrary = new Library() {
            // Interface RegisterInfo
            @Override
            public String getName() {
                String name = library.getName();
                hasText(name, String.format("非法的组件库名称:%s", name));
                return name;
            }

            @Override
            public String getChName() {
                String chName = library.getChName();
                hasText(chName, String.format("非法的组件库中文名称:%s", chName));
                return chName;
            }

            @Override
            public String getVersion() {
                String version = library.getVersion();
                version(version);
                return version;
            }

            @Override
            public Integer getType() {
                Integer type = library.getType();
                isEmpty(type,"请确认组件库类别");
                return type;
            }

            @Override
            public String getIntro() {
                String intro = library.getIntro();
                hasText(intro, "为提高组件的易用性, 请撰写组件库介绍");
                return intro;
            }

            @Override
            public String getChangeLog() {
                String changeLog = library.getChangeLog();
                hasText(changeLog, "请撰写组件库版本历史变更说明");
                return changeLog;
            }

            // Interface Library
            @Override
            public Object runKeyword(String keywordName, Map<String, Object> args) throws Exception {
                return library.runKeyword(keywordName, args);
            }

            @Override
            public Object runKeyword(String keywordName, IExecuteContext context) throws Exception {
                return library.runKeyword(keywordName, context);
            }

            @Override
            public String[] getKeywordNames() {
                return library.getKeywordNames();
            }

            @Override
            public String getKeywordDocumentation(String keywordName) throws KeywordNotFoundException {
                String doc = library.getKeywordDocumentation(keywordName);
                hasText(doc, String.format("请撰写组件[%s]注释信息", keywordName));
                return doc;
            }

            @Override
            public List<KeywordArgument> getKeywordArguments(String keywordName) throws Exception {
                return library.getKeywordArguments(keywordName);
            }

            @Override
            public Map<String, KeywordArgument> getKeywordArgumentMap(String keywordName) throws Exception {
                return library.getKeywordArgumentMap(keywordName);
            }

            @Override
            public String getKeywordAlias(String keywordName) throws KeywordNotFoundException {
                String alias = library.getKeywordAlias(keywordName);
                hasText(alias, String.format("非法的组件别名:%s", alias));
                return alias;
            }

            @Override
            public boolean existKeyword(String keywordName) {
                return library.existKeyword(keywordName);
            }

            @Override
            public List<KeywordInfo> getAllKeywords() throws Exception {
                return library.getAllKeywords();
            }

            @Override
            public Iterator<KeywordInfo> iterator() {
                return library.iterator();
            }

            @Override
            public void destroy() {
                try {
                    ThreadLevelCache.remove();
                } catch (Exception e) {
                }
                library.destroy();
            }
        };
        logger.debug("组件库已植入CCTP组件库编写规范校验, 调用库接口相关方法时自动完成规范校验.");
        return wrapLibrary;
    }
}