package com.ch.jedge.jbot.knbase.domain;

import com.ch.jedge.jbot.knbase.JedgeGptApp;
import com.ch.jedge.jbot.knbase.JedgeGptDomain;
import com.changhong.qlib.util.StringUtils;
import com.changhong.qlib.util.file.FileUtils;

import java.util.List;
import java.util.Locale;

public class JedgeGdeDomainParer {
    private final JedgeGptApp mGdeApp;
    public JedgeGptDomain tmpDomain;
    public final String ldgDomainFileName;
    private boolean handleKnOpen = false;
    private boolean parserFinalized = false;

    private int blockIndex = 0;
    private String currentBlockTitle = null;
    private String currentBlockContent = "";
    private String currentBlockHash = null;


    public JedgeGdeDomainParer(JedgeGptApp app, String ldeDomainFileName) {
        this.ldgDomainFileName = ldeDomainFileName;
        String domainName = FileUtils.getFilenameWithoutExt(ldeDomainFileName);
        this.mGdeApp = app;
        this.tmpDomain = new JedgeGptDomain(app, domainName, ldeDomainFileName);
    }

    public JedgeGptDomain parseGdeDomain() {
        List<String> lines = StringUtils.readStringLinesFromFile(ldgDomainFileName);
        for(String line : lines) {
            String realLine = trimComment(line);
            if(StringUtils.isNotValidStr(realLine)) continue;
            handleLine(realLine);
        }
        return handleComplete()? tmpDomain :null;
    }

    //处理行:  包括 //block//word/intent//{{/}}等知识分块标记等。
    // {{知识}}, 用于描述查询内容,以及intent的执行逻辑定义等。
    public void handleLine(String realLine) {
        if(parserFinalized) {
            mGdeApp.getMgModule().warnLog(String.format("Try to handle line on finalized parser : %s", realLine));
            return;
        }
        //处理内容,解析内容
        int idx = realLine.indexOf('=');
        if(idx>0) {
            String key = realLine.substring(0, idx).trim().toLowerCase(Locale.ROOT);
            String def = realLine.substring(idx+1);
            onKnDefLine(key, def);
        } else if( realLine.length() == 2 ) {
            switch (realLine) {
                case "{{":
                    if(this.handleKnOpen) {
                        mGdeApp.getMgModule().warnLog(String.format("Dual {{ before kn item closed : %s", realLine));
                        onKnItemClosed();
                    }
                    this.handleKnOpen = true;
                    this.currentBlockTitle = "";
                    this.currentBlockHash = JedgeGdeDomainBlock.makeBlockHashId(ldgDomainFileName, blockIndex);

                    break;
                case "}}":
                    onKnItemClosed();
                    break;
            }
        } else {    //知识数据， 在
            if(handleKnOpen) {
                //添加一个知识条目
                currentBlockContent += realLine;  //添加一个知识行
                currentBlockContent +="\n";
            }
        }
    }

    private void onKnItemClosed() {
        this.handleKnOpen = false;
        tmpDomain.addBlockContentOk(currentBlockHash, blockIndex, currentBlockTitle,currentBlockContent);
        currentBlockContent = "";
        currentBlockTitle = null;   //不在任何一个block中
        currentBlockHash = null;
        blockIndex++;
    }

    private void onKnDefLine(String key, String def) {
        if(JedgeGptApp.isDebugMode())
            mGdeApp.getMgModule().exMarkLog("[domainDef:%s]>>%s", key, def);
        //添加了属性
        switch (key) {
            case "word":
                onKeywordDefined(key, def, !handleKnOpen);
                break;
            case "intent":
                onIntentDefined(key, def, !handleKnOpen);
                break;
            case "block":
                currentBlockTitle = def;
                break;
            case "role":
                if(StringUtils.isValidStr(def) && !handleKnOpen)
                    tmpDomain.domainRole = def;
                break;
            case "title":
                if(this.handleKnOpen) {
                    mGdeApp.getMgModule().warnLog(String.format("[Warn!!!]>> title can not be set in block : %s", def));
                } else {
                    tmpDomain.setSubjectTitle(def);
                    onKeywordDefined(key, def, true);
                }
                break;
            default:
                mGdeApp.getMgModule().infoLog(String.format("[Unknown Domain Define type: %s]>>%s", key, def));
                break;
        }
    }

    private void onIntentDefined(String key, String def, boolean isGateItem) {
        if(StringUtils.isNotValidStr(def)) return;
        String[] keys = def.split(",");
        for(String k : keys ) {
            if(JedgeGptApp.isDebugMode())
                mGdeApp.getMgModule().highLog(String.format("[Keyword Def on (%d)%s]>>%s", blockIndex, currentBlockTitle, k));
            tmpDomain.pushGlobalWord(k, currentBlockHash, currentBlockTitle, isGateItem);
            tmpDomain.pushGateIntent(k, currentBlockHash, currentBlockTitle);
        }
    }

    private void onKeywordDefined(String key, String def, boolean isGateItem) {
        if(StringUtils.isNotValidStr(def)) return;
        String[] keys = def.split(",");
        for(String k : keys ) {
            tmpDomain.pushGlobalWord(k, currentBlockHash, currentBlockTitle, isGateItem);
        }
    }

    //解析完毕,检验合法性
    public boolean handleComplete() {
        if(StringUtils.isValidStr(currentBlockContent)) {
            //处理 {{ }}不配对等情况
            onKnItemClosed();
        }
        parserFinalized = true;
        return true;
    }

    private String trimComment(String line) {
        int s = line.indexOf("##");
        if(s>=0) {
            return line.substring(0,s).trim();
        }
        return line.trim();
    }

}
