package org.forks.jsonrpc;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.json.JSONObject;

public final class JsonRpcResult {
    private final Object mResult;

    JsonRpcResult(Object result) {
        super();
        mResult = result;
    }

    public Object getRaw() {
        return mResult;
    }

    public Integer getInt() {
        return (Integer) RpcTypeParser.sInt.fromJson(mResult);
    }

    public String getString() {
        return (String) RpcTypeParser.sString.fromJson(mResult);
    }

    public Short getShort() {
        return (Short) RpcTypeParser.sShort.fromJson(mResult);
    }

    public Long getLong() {
        return (Long) RpcTypeParser.sLong.fromJson(mResult);
    }

    public Short getByte() {
        return (Short) RpcTypeParser.sByte.fromJson(mResult);
    }

    public Double getDouble() {
        return (Double) RpcTypeParser.sDouble.fromJson(mResult);
    }

    public Boolean getBoolean() {
        return (Boolean) RpcTypeParser.sBoolean.fromJson(mResult);
    }

    public BigDecimal getDecimal() {
        return (BigDecimal) RpcTypeParser.sDecimal.fromJson(mResult);
    }

    public BigDecimal getMoney() {
        return getDecimal();
    }

    public boolean isNull() {
        return mResult == JSONObject.NULL;
    }

    public Date getDate() {
        return (Date) RpcTypeParser.sDate.fromJson(mResult);
    }

    public RpcObject getRpcObject(String objPath) throws JsonRpcException {
        return (RpcObject) RpcTypeParser.fromJson(mResult, objPath);
    }

    public DFDataTable getTable() {
        return (DFDataTable) RpcTypeParser.sTable.fromJson(mResult);
    }

    public ManyList getManyList(String objPath) throws JsonRpcException {
        return getByType("onetomany(" + objPath + ")");
    }

    public List<Integer> getIntList() throws JsonRpcException {
        return getByType("[int]");
    }

    public List<Short> getShortList() throws JsonRpcException {
        return getByType("[short]");
    }

    public List<Short> getByteList() throws JsonRpcException {
        return getByType("[byte]");
    }

    public List<Long> getLongList() throws JsonRpcException {
        return getByType("[long]");
    }

    public List<Boolean> getBooleanList() throws JsonRpcException {
        return getByType("[bool]");
    }

    public List<Double> getDoubleList() throws JsonRpcException {
        return getByType("[double]");
    }

    public List<String> getStringList() throws JsonRpcException {
        return getByType("[str]");
    }

    public List<Date> getDateList() throws JsonRpcException {
        return getByType("[datetime]");
    }

    public List<BigDecimal> getDecimalList() throws JsonRpcException {
        return getByType("[decimal]");
    }

    public List<BigDecimal> getMoneyList() throws JsonRpcException {
        return getByType("[money]");
    }

    public List<RpcObject> getRpcObjectList(String objPath)
            throws JsonRpcException {
        return getByType("[" + objPath + "]");
    }

    public Map<String, Integer> getIntMap() throws JsonRpcException {
        return getByType("{str:int}");
    }

    public Map<String, Short> getByteMap() throws JsonRpcException {
        return getByType("{str:byte}");
    }

    public Map<String, Short> getShortMap() throws JsonRpcException {
        return getByType("{str:short}");
    }

    public Map<String, Long> getLongMap() throws JsonRpcException {
        return getByType("{str:long}");
    }

    public Map<String, Boolean> getBooleanMap() throws JsonRpcException {
        return getByType("{str:bool}");
    }

    public Map<String, Double> getDoubleMap() throws JsonRpcException {
        return getByType("{str:double}");
    }

    public Map<String, String> getStringMap() throws JsonRpcException {
        return getByType("{str:str}");
    }

    public Map<String, Date> getDateMap() throws JsonRpcException {
        return getByType("{str:datetime}");
    }

    public Map<String, BigDecimal> getDecimalMap() throws JsonRpcException {
        return getByType("{str:decimal}");
    }

    public Map<String, BigDecimal> getMoneyMap() throws JsonRpcException {
        return getByType("{str:money}");
    }

    public Map<String, RpcObject> getRpcObjectMap(String objPath)
            throws JsonRpcException {
        return getByType("{str:" + objPath + "}");
    }

    private <T> T getByType(String rpcType) throws JsonRpcException {
        RpcType type = RpcTypeParser.parse(rpcType);
        return (T) type.fromJson(mResult);
    }

    JSONObject getJsonObject() {
        if (isNull()) {
            return null;
        }
        return (JSONObject) mResult;
    }
}
