package cn.com.ctop.crawler.modules.core.util;

public class JsonHelper {
    public String json;
    public int nextIdx;

    public JsonHelper(String json) {
        this.json = json;
        this.nextIdx = 0;
    }

    public void skip() {
        while (nextIdx < json.length()) {
            char c = json.charAt(nextIdx);
            if ((c <= 32) || (c == '\\')) {
                nextIdx++;
            } else {
                break;
            }
        }
    }

    public String NextSToken() {
        StringBuilder ret = new StringBuilder();
        while (nextIdx < json.length()) {
            char c = json.charAt(nextIdx);
            if (c == '\"') {
                break;
            }
            if ((c == '\\') && (nextIdx + 1 < json.length())) {
                if (json.charAt(nextIdx + 1) == '\\') {
                    ret.append('\\');
                    nextIdx += 2;
                    continue;
                }
                if (json.charAt(nextIdx + 1) == '\"') {
                    ret.append('\"');
                    nextIdx += 2;
                    continue;
                }
            }
            ret.append(c);
            nextIdx++;
        }
        return ret.toString();
    }

    public String NextNToken() {
        String ret = "";
        while (nextIdx < json.length()) {
            char c = json.charAt(nextIdx);
            if (c == '\\') {
                nextIdx++;
                continue;
            }
            if ((c < '0' || c > '9') && c != '.') {
                // not number
                break;
            }
            ret += c;
            nextIdx++;
        }
        return ret;
    }

    public void Key2Val(FateadmHttpUtil.HttpResp rsp, String key, String val) {
        if ("RetCode".equals(key)) {
            rsp.retCode = Integer.parseInt(val);
        } else if ("ErrMsg".equals(key)) {
            rsp.errMsg = val;
        } else if ("RequestId".equals(key)) {
            rsp.reqId = val;
        } else if ("RspData".equals(key)) {
            rsp.rspData = val;
        } else if ("result".equals(key)) {
            rsp.predResl = val;
        } else if ("cust_val".equals(key)) {
            rsp.custVal = Double.parseDouble(val);
        }
    }

    public void Parse(FateadmHttpUtil.HttpResp rsp) {
        nextIdx = 0;
        String key = "";
        String sval = "";
        for (nextIdx = 0; nextIdx < json.length(); ) {
            skip();
            char c = json.charAt(nextIdx);
            switch (c) {
                case ':':
                case ',':
                    break;
                case '[':
                case '{':
                case '}':
                case ']':
                    // not support here
                    break;
                case '\"':
                    nextIdx++;
                    sval = NextSToken();
                    skip();
                    if (nextIdx >= json.length()) {
                        break;
                    }
                    if (json.charAt(nextIdx + 1) == ':') {
                        key = sval;
                        nextIdx++;
                        continue;
                    }
                    // key to val
                    Key2Val(rsp, key, sval);
                    key = "";
                    break;
                case '+':
                case '-':
                case '.':
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    // is number
                    sval = NextNToken();
                    // key to val
                    Key2Val(rsp, key, sval);
                    key = "";
                    break;
                case 'n':
                case 'N':
                    sval = json.substring(nextIdx, 4).toLowerCase();
                    if (!"null".equals(sval)) {
                        //error
                        break;
                    }
                    sval = "";
                    nextIdx += 4;
                    // key to val
                    Key2Val(rsp, key, sval);
                    key = "";
                    break;
                default:
                    break;
            }
            nextIdx++;
        }
    }
}
