package org.bdware.sc.boundry.utils;

import com.google.gson.JsonObject;
import org.bdware.doip.application.client.ContractDOAClient;
import org.bdware.doip.core.doipMessage.DoipMessage;
import org.bdware.doip.core.exception.DoDecodeException;
import org.bdware.doip.core.exception.IrpClientException;
import org.bdware.doip.core.model.digitalObject.DigitalObject;
import org.bdware.doip.core.model.digitalObject.Element;
import org.bdware.doip.core.utils.DoipGson;
import org.bdware.sc.compiler.PermissionStub;
import org.bdware.sc.node.Permission;
import org.bdware.sc.util.JsonUtil;

import java.io.IOException;

@PermissionStub(permission = Permission.DOIP)
public class DOIPUtil {
    //    private static final Logger LOGGER = LogManager.getLogger(DOIPUtil.class);
    public static ContractDOAClient doaClient = null;

    static {
        initClient();
    }

    public static String test(String doi) {
        return "create DOClient And hello " + doi + " World";
    }

    public static String hello(String repoID) {
        initClient();
        DigitalObject respDO;
        DoipMessage msg;
        try {
            msg = doaClient.hello(repoID);
        } catch (IrpClientException ie) {
            ie.printStackTrace();
            return "send doip message error: " + ie.getMessage();
        }
        try {
            respDO = msg.body.getDataAsDigitalObject();
            return respDO.toString();
        } catch (DoDecodeException | IOException e) {
            e.printStackTrace();
            return new String(msg.body.getEncodedData());
        }
    }

    public static String retrieve(String doi, String args) {
        initClient();
        DigitalObject respDO;
        DoipMessage msg;
        JsonObject argObj = JsonUtil.fromJson(args, JsonObject.class);
        String elementID = argObj.get("elementID") == null ? null : argObj.get("elementID").getAsString();
        boolean includeElementData =
                argObj.get("includeElementData") != null &&
                        argObj.get("includeElementData").getAsString().equals("true");
        try {
            msg = doaClient.retrieve(doi, elementID, includeElementData);
        } catch (IrpClientException ie) {
            ie.printStackTrace();
            return "send doip message error: " + ie.getMessage();
        }
        try {
            respDO = msg.body.getDataAsDigitalObject();
            return respDO.toString();
        } catch (DoDecodeException | IOException e) {
            e.printStackTrace();
            return new String(msg.body.getEncodedData());
        }
    }

    public static String call(String doi, String action, String args) {
        initClient();
        DoipMessage msg;
        try {
            msg = doaClient.call(doi, action, args.getBytes());
            return msg.body.getDataAsJsonString();
        } catch (IrpClientException e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }

    public static String create(String repoID, String doString) {
        initClient();
        DigitalObject respDO;
        DoipMessage msg;
        DigitalObject dObj = DoipGson.getDoipGson().fromJson(doString, DigitalObject.class);
        for (Element e : dObj.elements) {
            if (null != e.dataString) {
                e.setData(e.dataString.getBytes());
            }
            e.dataString = null;
        }
        try {
            msg = doaClient.create(repoID, dObj);
        } catch (IrpClientException ie) {
            ie.printStackTrace();
            return "send doip message error: " + ie.getMessage();
        }
        try {
            respDO = msg.body.getDataAsDigitalObject();
            return respDO.toString();
        } catch (DoDecodeException | IOException e) {
            e.printStackTrace();
            return new String(msg.body.getEncodedData());
        }
    }

    public static String delete(String doID, String repoID) {
        initClient();
        DigitalObject respDO;
        DoipMessage msg;
        try {
            msg = doaClient.delete(doID, repoID);
        } catch (IrpClientException ie) {
            ie.printStackTrace();
            return "send doip message error: " + ie.getMessage();
        }
        try {
            respDO = msg.body.getDataAsDigitalObject();
            return respDO.toString();
        } catch (DoDecodeException | IOException e) {
            e.printStackTrace();
            return new String(msg.body.getEncodedData());
        }
    }

    public static String listOperation(String doID) {
        initClient();
        DigitalObject respDO;
        DoipMessage msg;
        try {
            msg = doaClient.listOperations(doID);
        } catch (IrpClientException ie) {
            ie.printStackTrace();
            return "send doip message error: " + ie.getMessage();
        }
        try {
            respDO = msg.body.getDataAsDigitalObject();
            return respDO.toString();
        } catch (DoDecodeException | IOException e) {
            e.printStackTrace();
            return new String(msg.body.getEncodedData());
        }
    }


//    public static String create(String repoID, ScriptObjectMirror doStr){
//        logger.debug(JsonUtil.toJson(doStr));
//        SM2KeyPair kp = JavaScriptEntry.getKeyPair();
//        HandleServiceUtils.CustomizeHandleService(kp,JavaScriptEntry.doi,HandleServiceUtils.LHS_Address);
//        DOAClient client = DOAClient.getGlobalInstance();
//        logger.debug(JsonUtil.toJson(doStr));
//        DigitalObject digitalObject = new DigitalObject(
//                doStr.get("doID").toString(),
//                DoType.DoString
//        );
//        digitalObject.addAttribute("content", doStr.get("doBody").toString());
//        try {
//            return new String(client.create(repoID,digitalObject).parameters.toByteArray());
//        }catch (Exception e){
//            e.printStackTrace();
//            return e.getMessage();
//        }
//    }

//    public static String update(ScriptObjectMirror doStr){
//        SM2KeyPair kp = JavaScriptEntry.getKeyPair();
//        HandleServiceUtils.CustomizeHandleService(kp,JavaScriptEntry.doi,HandleServiceUtils.LHS_Address);
//        DOAClient client = DOAClient.getGlobalInstance();
//        DigitalObject digitalObject = new DigitalObject(
//                doStr.get("doID").toString(),
//                DoType.DoString
//        );
//        digitalObject.addAttribute("content", doStr.get("doBody").toString());
//        try {
//            return new String(client.update(digitalObject).parameters.toByteArray());
//        }catch (Exception e){
//            e.printStackTrace();
//            return e.getMessage();
//        }
//    }


    public static void initClient() {
        if (null == doaClient) {
            doaClient = ContractDOAClient.getContractDOAClientForTest();
        }
    }
}
