/*
 * Copyright (c) 2017 CEA.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    CEA - initial API and implementation
 */
package org.eclipse.sensinact.gateway.util;

import org.eclipse.sensinact.gateway.util.json.JSONValidator;
import org.json.JSONArray;
import org.json.JSONObject;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * JSON Helpers
 *
 * @author <a href="mailto:christophe.munilla@cea.fr">Christophe Munilla</a>
 */
public class JSONUtils {
    protected static final Logger LOGGER = Logger.getLogger(JSONUtils.class.getCanonicalName());

    public static final int DEFAULT_MAX_DEEP = 3;

    /**
     * Returns the JSON formated string representation
     * of the {@link Object} passed as parameter, according
     * to the DEFAULT_MAX_DEEP constant value possible
     * iterations through the object hierarchy
     *
     * @param object the {@link Object} to describe as a JSON
     *               formated string
     * @return the JSON formated string representation
     */
    public static String toJSONFormat(Object object) {
        return JSONUtils.toJSONFormat(object, new JSONUtils.JSONWriterContext(DEFAULT_MAX_DEEP, object));
    }

    /**
     * Returns the JSON formated string representation
     * of the {@link Object} passed as parameter according
     * to the number passed as parameter of possible
     * iterations through the object hierarchy
     *
     * @param object the {@link Object} to describe as a JSON
     *               formated string
     * @param deep   number of possible iterations through the
     *               object hierarchy
     * @return the JSON formated string representation
     */
    public static String toJSONFormat(Object object, int deep) {
        return JSONUtils.toJSONFormat(object, new JSONUtils.JSONWriterContext(deep, object));
    }

    /**
     * Returns the JSON formated string representation
     * of the {@link Object} passed as parameter
     *
     * @param object  the {@link Object} to return a JSON
     *                formated string representation of
     * @param context state of the process
     * @return the JSON formated string representation
     */
    public static String toJSONFormat(Object object, JSONUtils.JSONWriterContext context) {
        if (object == null) {
            return JSON_NULL;
        }
        if (JSONObject.class.isAssignableFrom(object.getClass())) {
            return ((JSONObject) object).toString();
        }
        if (JSONArray.class.isAssignableFrom(object.getClass())) {
            return ((JSONArray) object).toString();
        }
        if (object.getClass().isArray()) {
            return JSONUtils.arrayToJSONFormat(object, context);
        }
        if (List.class.isAssignableFrom(object.getClass())) {
            return toJSONFormat(((List) object).toArray(new Object[0]), context);
        }
        if (Map.class.isAssignableFrom(object.getClass())) {
            Iterator<Map.Entry> iterator = ((Map) object).entrySet().iterator();
            int index = 0;
            StringBuilder builder = new StringBuilder();
            builder.append(JSONUtils.OPEN_BRACE);

            while (iterator.hasNext()) {
                Map.Entry entry = iterator.next();
                String key = toJSONFormat(entry.getKey());
                if (key == null) {
                    continue;
                }
                builder.append(index > 0 ? JSONUtils.COMMA : JSONUtils.EMPTY);
                if (!key.startsWith("\"")) {
                    builder.append(JSONUtils.QUOTE);
                    builder.append(key);
                    builder.append(JSONUtils.QUOTE);

                } else {
                    builder.append(key);
                }
                builder.append(JSONUtils.COLON);
                builder.append(toJSONFormat(entry.getValue()));
                index++;
            }
            builder.append(JSONUtils.CLOSE_BRACE);
            return builder.toString();
        }
        if (String.class == object.getClass() && new JSONValidator((String) object).valid()) {
            return (String) object;
        }
        if (CastUtils.isPrimitive(object.getClass())) {
            return JSONUtils.primitiveToJSONFormat(object);

        } else if (object.getClass().isEnum()) {
            return JSONUtils.primitiveToJSONFormat(((Enum) object).name());
        } else {
            try {
                Method method = object.getClass().getDeclaredMethod("getJSON");

                if (method.getReturnType() == String.class) {
                    return (String) method.invoke(object);
                }
            } catch (Exception e) {
                LOGGER.log(Level.CONFIG, "Object to cast is not a JSONable instance");
            }
        }
        if (context.tooDeep() || context.circularReference()) {
            return new StringBuilder().append(QUOTE).append(object.toString()).append(QUOTE).toString();
        }
        StringBuilder builder = new StringBuilder();
        builder.append(OPEN_BRACE);
        for (Field field : object.getClass().getDeclaredFields()) {
            if (field.isAccessible()) {
                String fieldJSON = null;
                try {
                    context.decrementAndGet();
                    fieldJSON = toJSONFormat(field.get(object), context);

                } catch (Exception e) {
                    continue;
                }
                if (fieldJSON != null && fieldJSON.length() > 0) {
                    builder.append(QUOTE);
                    builder.append(field.getName());
                    builder.append(QUOTE);
                    builder.append(COLON);
                    builder.append(fieldJSON);
                }
            }
        }
        builder.append(CLOSE_BRACE);
        return builder.toString();
    }

    /**
     * Returns the JSON formated string representation
     * of the {@link Array} passed as parameter
     *
     * @param array   the {@link array} to represent as a JSON
     *                formated string
     * @param context the state of the process
     * @return the JSON formated string representation
     */
    private static String arrayToJSONFormat(Object array, JSONWriterContext context) {
        StringBuilder builder = new StringBuilder();
        builder.append(OPEN_BRACKET);

        int length = Array.getLength(array);
        for (int i = 0; i < length; i++) {
            context.decrementAndGet();
            String json = JSONUtils.toJSONFormat(Array.get(array, i), context);

            if (json != null && json.length() > 0) {
                builder.append(builder.length() > 1 ? COMMA : EMPTY);
                builder.append(json);
            }
        }
        builder.append(CLOSE_BRACKET);
        return builder.toString();
    }

    /**
     * Returns the JSON formated string representation of
     * the Primitive object passed as parameter
     *
     * @param primitive the Primitive object to return the JSON formated
     *                  string representation of
     * @return the JSON formated string representation of
     * the Primitive object passed as parameter
     */
    private static String primitiveToJSONFormat(Object primitive) {
        StringBuilder builder = new StringBuilder();
        Class<?> argClass = primitive.getClass();

        if (CastUtils.isPrimitive(argClass)) {
            if (String.class.equals(argClass) || Character.class.equals(argClass) || char.class.equals(argClass)) {
                builder.append(QUOTE);
                builder.append(primitive);
                builder.append(QUOTE);

            } else {
                builder.append(String.valueOf(primitive));
            }
        } else {
            return JSON_NULL;
        }
        return builder.toString();
    }

    /**
     * JSON writing process context
     * TODO : handle circular reference
     */
    private static final class JSONWriterContext {
        public final Object jsonable;
        private int deep = 0;

        JSONWriterContext(int deep, Object jsonable) {
            this.jsonable = jsonable;
            this.deep = deep;
        }

        public boolean circularReference() {
            //TODO : implement
            return false;
        }

        int decrementAndGet() {
            return --deep;
        }

        boolean tooDeep() {
            return deep < 0;
        }
    }

    public static final String EMPTY = "";

    //JSON-RPC GRAMMAR
    public static final String JSON_RPC_NAME = "jsonrpc";
    public static final String JSON_RPC_VERSION = "2.0";
    public static final String JSON_RPC_ID = "id";
    public static final String JSON_RPC_FUNCTION = "function";
    public static final String JSON_RPC_PROCEDURE = "procedure";
    public static final String JSON_RPC_METHOD = "method";
    public static final String JSON_RPC_PARAMS = "params";
    public static final String JSON_RPC_RESULT = "result";
    public static final String JSON_RPC_ERROR = "error";
    public static final String JSON_RPC_MESSAGE = "message";
    public static final String JSON_RPC_CODE = "code";

    //JSON KEY-WORDS
    public static final String JSON_TRUE = "true";
    public static final String JSON_FALSE = "false";
    public static final String JSON_NULL = "null";

    //JSON DELIMITERS
    public static final char OPEN_BRACE = '{';
    public static final char CLOSE_BRACE = '}';
    public static final char OPEN_BRACKET = '[';
    public static final char CLOSE_BRACKET = ']';
    public static final char COMMA = ',';
    public static final char QUOTE = '\"';
    public static final char APOSTROPHE = '\'';
    public static final char COLON = ':';
    public static final char SEMICOLON = ';';
}
