package org.bdware.sc.bean;

import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;

import java.io.*;

public class ContractRequest extends SM2Verifiable
        implements Serializable, Comparable<ContractRequest> {
    private static final long serialVersionUID = 5516141428163407726L;
    public long hasValue;
    public long gasLimit;
    public Boolean needSeq = false; // not requestAll do not need sequent
    public int seq = 0; // only requestAll type contract need
    public boolean withDynamicAnalysis = false;
    public boolean withEvaluatesAnalysis = false;
    public String fromContract;
    String contractID;
    String contractDOI;
    // requester = reqPubKey
    String requester;
    // DOI of requester
    String requesterDOI;
    // action = rsaPrivKeyEncoded(aesKey);
    String action;
    JsonElement arg;
    String requestID;
    boolean fromDebug = false;

    public static ContractRequest parse(byte[] content) {
        try {
            ObjectInputStream input = new ObjectInputStream(new ByteArrayInputStream(content));
            return (ContractRequest) input.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public String getContractID() {
        return contractID;
    }

    public ContractRequest setContractID(String id) {
        contractID = id;
        return this;
    }

    public String getContractDOI() {
        return contractDOI;
    }

    public void setContractDOI(String doi) {
        contractDOI = doi;
    }

    public String getRequester() {
        return requester;
    }

    public void setRequester(String requester) {
        this.requester = requester;
    }

    public String getRequesterDOI() {
        if (null == requesterDOI || requesterDOI.isEmpty()) {
            return "empty";
        }
        return requesterDOI;
    }

    public void setRequesterDOI(String requesterDOI) {
        this.requesterDOI = requesterDOI;
    }

    public JsonElement getArg() {
        return arg;
    }

    public ContractRequest setArg(String arg) {
        return setArg(new JsonPrimitive(arg));
    }

    public ContractRequest setArg(JsonElement arg) {
        this.arg = arg;
        return this;
    }


    public String getAction() {
        return action;
    }

    public ContractRequest setAction(String action) {
        this.action = action;
        return this;
    }

    public long getValue() {
        return hasValue;
    }

    public ContractRequest setValue(long hasValue) {
        this.hasValue = hasValue;
        return this;
    }

    public long getGasLimit() {
        return gasLimit;
    }

    public void setGasLimit(long gasLimit) {
        this.gasLimit = gasLimit;
    }

    public void setFromDebug(boolean fromDebug) {
        this.fromDebug = fromDebug;
    }

    public boolean fromDebug() {
        return fromDebug;
    }

    @Override
    public String getPublicKey() {
        return requester;
    }

    @Override
    public void setPublicKey(String pubkey) {
        setRequester(pubkey);
    }

    @Override
    public String getContentStr() {
        return String.format(
                "%s|%s|%s%s|%s",
                (contractDOI != null && contractDOI.length() > 0) ? contractDOI : contractID,
                action,
                parseArg(),
                gasLimit > 0 ? "|" + gasLimit : "",
                requester);
    }

    private String parseArg() {
        try {
            return arg.getAsString();
        } catch (Exception e) {
            return arg.toString();
        }
    }

    public byte[] toByte() {
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ObjectOutputStream bo = new ObjectOutputStream(out);
            bo.writeObject(this);
            return out.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public String getRequestID() {
        return requestID;
    }

    public void setRequestID(String str) {
        this.requestID = str;
    }

    @Override
    public int compareTo(ContractRequest cr) {
        return Integer.compare(seq, cr.seq);
    }
}
