package org.bdware.sc.engine.hook;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.ContractResult;
import org.bdware.sc.JSEngine;
import org.bdware.sc.boundry.JavaScriptEntry;
import org.bdware.sc.node.AnnotationHook;
import org.bdware.sc.node.ArgPacks;
import org.bdware.sc.node.FunctionNode;
import org.bdware.sc.util.JsonUtil;
import org.paillier.PaillierKeyPair;

import java.security.interfaces.RSAPrivateKey;

public class HomomorphicDecryptHandler implements AnnotationHook {
    private static final Logger LOGGER = LogManager.getLogger(ObjToJsonHandler.class);

    private final FunctionNode fun;

    public HomomorphicDecryptHandler(FunctionNode fun) {
        this.fun = fun;
    }

    @Override
    public ArgPacks handle(JSEngine engine, ArgPacks argPacks) {
        try {
//            GetHomArgs args =
//                    new GetHomArgs(
//                            input.getRequester(), this.fun.getSecretID().replaceAll("\"", ""));
//            String arg = JsonUtil.toJson(args);
            JsonElement homoDecryptConf = this.fun.getHomoDecryptConf();
            if (null != homoDecryptConf && !homoDecryptConf.isJsonNull()) {
                String res = (String)
                        JavaScriptEntry.executeContract(
                                "keyManager_1",
                                "getPrivKey",
                                this.fun.getSecretID().replaceAll("\"", ""));
                LOGGER.info("HomomorphicDecryptHandler--------------------------------1: " + res);
                ContractResult results = JsonUtil.fromJson(res, ContractResult.class);
                String privKeyStr = results.result.getAsString();
                LOGGER.info("HomomorphicEncryptHandler--------------------------------2: " + privKeyStr);
                RSAPrivateKey privkey = (RSAPrivateKey) PaillierKeyPair.pemToPrivateKey(privKeyStr);
                LOGGER.info("HomomorphicEncryptHandler--------------------------------3: " + privkey);
                HomoVisitor.privateKey = privkey;
                argPacks.ret = getDecryptResult(homoDecryptConf, JsonUtil.parseObject(argPacks.ret));
                if (null != argPacks.ret) {
                    return argPacks;
                }
                argPacks.ret = new JsonObject();
            }
            return argPacks;
            // return ret;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return argPacks;
    }

    private Object getDecryptResult(JsonElement homoDecryptConf, JsonElement data) {
        if (null == homoDecryptConf) {
            return data;
        }
        HomoVisitor visitor = new HomoVisitor(data);
        visitor.visit(homoDecryptConf);

        JsonElement root = visitor.get();
        LOGGER.info("HomoRetInvoke: " + root);
        return root;
    }
}
