package org.bdware.sc.engine.hook;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.JSEngine;
import org.bdware.sc.bean.ContractRequest;
import org.bdware.sc.boundry.ScriptReturnException;
import org.bdware.sc.node.AnnotationHook;
import org.bdware.sc.node.AnnotationNode;
import org.bdware.sc.node.ArgPacks;
import org.bdware.sc.node.FunctionNode;

@YJSAnnotation(name = "ArgSchema")
public class ArgSchemaHandler implements AnnotationHook {
    private AnnotationNode a;
    private static final Logger LOGGER = LogManager.getLogger(ArgSchemaHandler.class);

    public ArgSchemaHandler(AnnotationNode annoNode) {
        a = annoNode;
        String arg = a.getArgs().get(0);
//        if (arg.startsWith("/")){
//            ;//ContractProcess.instance.engine.getResources().loadAsString(arg);
//        }else {
//            ;
//        }
    }

    public static ArgSchemaHandler fromAnnotationNode(FunctionNode funNode, AnnotationNode annoNode) {
        return new ArgSchemaHandler(annoNode);
    }

    @Override
    public ArgPacks handle(JSEngine Engine, ArgPacks argPacks) throws ScriptReturnException {
        ContractRequest input = argPacks.request;
        JsonElement je = input.getArg();
        ArgSchemaVisitor visitor;
        if (je.isJsonObject())
            visitor = new ArgSchemaVisitor(input.getArg().getAsJsonObject());
        else {
            try {
                JsonElement obj = JsonParser.parseString(input.getArg().getAsString());
                visitor = new ArgSchemaVisitor(obj);
                //IMPORTANT automatically convert arg type here
                input.setArg(obj);
                argPacks.arg = obj;
            } catch (Exception e) {
                e.printStackTrace();
                JsonObject jo = new JsonObject();
                jo.addProperty("msg", "[Illegal Type] argument should be JSON");
                jo.addProperty("code", 1004);
                throw new ScriptReturnException(jo);
            }
        }
        if (je.toString().isEmpty() && !a.getArgs().get(0).equals("")) {
            JsonObject jo = new JsonObject();
            jo.addProperty("msg", "[Empty argument] argument should not be empty");
            jo.addProperty("code", 1003);
            throw new ScriptReturnException(jo);
        }
        visitor.visit(JsonParser.parseString(a.getArgs().get(0)));
        if (!visitor.getStatus()) {
            JsonObject jo = new JsonObject();
            jo.addProperty("msg", visitor.getException());
            jo.addProperty("code", visitor.errorCode);
            throw new ScriptReturnException(jo);
        }
        return argPacks;
    }
}
