package org.bdware.sc.engine.hook;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import org.bdware.mockjava.JsonVisitor;

public class ArgSchemaVisitor extends JsonVisitor {
    JsonElement root;
    public boolean status = true;
    public int errorCode = 0;
    //{"msg":"xxx","code":1000}
    //
//    JsonElement message = new JsonPrimitive("");
    public String message = "";

    public ArgSchemaVisitor(JsonElement ret) {
        root = ret;
    }

    @Override
    public JsonVisitor visitObject(JsonObject schema) {
        //message = new JsonObject();
        if (root.isJsonObject()) {
            JsonObject jo = root.getAsJsonObject();
            for (String key : schema.keySet()) {
                if (key.startsWith("!")) {
                    //TODO
                    //if(必選）
                    if (jo.has(key.substring(1))) {
                        ArgSchemaVisitor visitor = new ArgSchemaVisitor(jo.get(key.substring(1)));
                        visitor.visit(schema.get(key));
                        if (!visitor.status) {
                            errorCode += visitor.errorCode;
                            message += visitor.message;
                        }
                        status &= visitor.status;
                    } else {
                        message += "[Missing argument] " + key.substring(1) + " should be supplied ";
                        status = false;
                        errorCode = 1002;
                    }
                } else {
                    if (jo.has(key)) {
                        ArgSchemaVisitor visitor = new ArgSchemaVisitor(jo.get(key));
                        visitor.visit(schema.get(key));
                        if (!visitor.status) {
                            message += visitor.message;
                            errorCode += visitor.errorCode;
                        }
                        status &= visitor.status;
                    }
                }
            }
        } else {
            message += "[Incorrect type] should be object";
            status = false;
            errorCode = 1003;
        }
        return this;
    }

    @Override
    public JsonVisitor visitJsonArray(JsonArray ele) {
        if (root.isJsonArray()) {
            JsonArray array = root.getAsJsonArray();
            for (int i = 0; i < array.size(); i++) {
                ArgSchemaVisitor visitor = new ArgSchemaVisitor(array.get(i));
                visitor.visit(ele.get(0));
                message += visitor.message;
                status &= visitor.status;
            }
        }
        return this;
    }

    public JsonElement get() {
        return root;
    }

    @Override

    public JsonVisitor visitPrimitive(JsonPrimitive primitive) {
        //
        if (primitive.isString()) {
            String type = primitive.getAsString();
            try {
                String result = "";
                //md5不需要参数
                if (type.equals("string")) {
                    if (root.isJsonPrimitive() && root.getAsJsonPrimitive().isString()) {
                        return this;
                    } else {
                        message = "[Type error] The value (" + root.getAsJsonPrimitive().getAsString() + ") should be string";
                        status = false;
                        errorCode = 1001;
                        return this;
                    }
                } else if (type.equals("number")) {
                    if (root.isJsonPrimitive() && root.getAsJsonPrimitive().isNumber()) {
                        return this;
                    } else {
                        message = "[Type error] The value (" + root.getAsJsonPrimitive().getAsString() + ") should be number";
                        status = false;
                        errorCode = 1001;
                        return this;
                    }
                } else if (type.equals("boolean")) {
                    if (root.isJsonPrimitive() && root.getAsJsonPrimitive().isBoolean()) {
                        return this;
                    } else {
                        message = "[Type error] The value (" + root.getAsJsonPrimitive().getAsString() + ") should be boolean";
                        status = false;
                        errorCode = 1001;
                        return this;
                    }
                } else if (type.equals("[]")) {
                    if (root.isJsonArray()) {
                        return this;
                    } else {
                        message = "[Type error] The value (" + root.getAsJsonPrimitive().getAsString() + ") should be array";
                        status = false;
                        errorCode = 1001;
                        return this;
                    }
                } else if (type.equals("{}")) {
                    if (root.isJsonObject()) {
                        return this;
                    } else {
                        message = "[Type error] The value (" + root.getAsJsonPrimitive().getAsString() + ") should be object";
                        status = false;
                        errorCode = 1001;
                        return this;
                    }
                }

            } catch (Exception e) {
                System.out.println(e);
            }
        }
        return this;
    }

    public boolean getStatus() {
        return status;
    }

    public String getException() {
        return message;
    }
}
