/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.struts2.json;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.zip.GZIPOutputStream;
import java.util.Arrays;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.opensymphony.xwork2.inject.Container;
import com.opensymphony.xwork2.inject.Inject;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.struts2.json.annotations.SMDMethod;

import com.opensymphony.xwork2.util.TextParseUtil;
import com.opensymphony.xwork2.util.WildcardUtil;

/**
 * Wrapper for JSONWriter with some utility methods.
 */
public class JSONUtil {

    public final static String RFC3339_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
    public static final boolean CACHE_BEAN_INFO_DEFAULT = true;
    
    private static final Logger LOG = LogManager.getLogger(JSONUtil.class);

    private JSONWriter writer;

    public void setWriter(JSONWriter writer) {
        this.writer = writer;
    }

    @Inject
    public void setContainer(Container container) {
        setWriter(container.getInstance(JSONWriter.class, container.getInstance(String.class,
                JSONConstants.JSON_WRITER)));
    }

    /**
     * Serializes an object into JSON.
     *
     * @param object
     *            to be serialized
     * @param cacheBeanInfo
     * 			  Specifies whether to cache bean info in the JSONWriter
     * @return JSON string
     * @throws JSONException in case of error during serialize
     */
    public String serialize(Object object, boolean cacheBeanInfo) throws JSONException {
        writer.setCacheBeanInfo(cacheBeanInfo);
        return writer.write(object);
    }

    /**
     * Serializes an object into JSON, excluding any properties matching any of
     * the regular expressions in the given collection.
     *
     * @param object
     *            to be serialized
     * @param excludeProperties
     *            Patterns matching properties to exclude
     * @param includeProperties
     *            Patterns matching properties to include
     * @param ignoreHierarchy
     *            whether to ignore properties defined on base classes of the
     *            root object
     * @param excludeNullProperties
     *            enable/disable excluding of null properties
     * @return JSON string
     * @throws JSONException in case of error during serialize
     */
    public String serialize(Object object, Collection<Pattern> excludeProperties,
            Collection<Pattern> includeProperties, boolean ignoreHierarchy, boolean excludeNullProperties)
            throws JSONException {
    	return serialize(object, excludeProperties, includeProperties, 
    			ignoreHierarchy, excludeNullProperties, CACHE_BEAN_INFO_DEFAULT);        
    }
    
    /**
     * Serializes an object into JSON, excluding any properties matching any of
     * the regular expressions in the given collection.
     *
     * @param object
     *            to be serialized
     * @param excludeProperties
     *            Patterns matching properties to exclude
     * @param includeProperties
     *            Patterns matching properties to include
     * @param ignoreHierarchy
     *            whether to ignore properties defined on base classes of the
     *            root object
     * @param excludeNullProperties
     *            enable/disable excluding of null properties
     * @param cacheBeanInfo
     * 			  Specifies whether to cache bean info in the JSONWriter
     * @return JSON string
     * @throws JSONException in case of error during serialize
     */
    public String serialize(Object object, Collection<Pattern> excludeProperties,
            Collection<Pattern> includeProperties, boolean ignoreHierarchy, boolean excludeNullProperties,
            boolean cacheBeanInfo)
            throws JSONException {
        writer.setIgnoreHierarchy(ignoreHierarchy);
        writer.setCacheBeanInfo(cacheBeanInfo);
        return writer.write(object, excludeProperties, includeProperties, excludeNullProperties);
    }

    /**
     * Serializes an object into JSON, excluding any properties matching any of
     * the regular expressions in the given collection.
     *
     * @param object
     *            to be serialized
     * @param excludeProperties
     *            Patterns matching properties to exclude
     * @param includeProperties
     *            Patterns matching properties to include
     * @param ignoreHierarchy
     *            whether to ignore properties defined on base classes of the
     *            root object
     * @param enumAsBean
     *            whether to serialized enums a Bean or name=value pair
     * @param excludeNullProperties
     *            enable/disable excluding of null properties
     * @param defaultDateFormat
     *            date format used to serialize dates
     * @return JSON string
     * @throws JSONException in case of error during serialize
     */
    public String serialize(Object object, Collection<Pattern> excludeProperties,
                                   Collection<Pattern> includeProperties, boolean ignoreHierarchy, boolean enumAsBean,
                                   boolean excludeNullProperties, String defaultDateFormat) throws JSONException {
    	return serialize(object, excludeProperties, includeProperties, ignoreHierarchy, enumAsBean, 
    			excludeNullProperties, defaultDateFormat, CACHE_BEAN_INFO_DEFAULT);        
    }
    
    /**
     * Serializes an object into JSON, excluding any properties matching any of
     * the regular expressions in the given collection.
     *
     * @param object
     *            to be serialized
     * @param excludeProperties
     *            Patterns matching properties to exclude
     * @param includeProperties
     *            Patterns matching properties to include
     * @param ignoreHierarchy
     *            whether to ignore properties defined on base classes of the
     *            root object
     * @param enumAsBean
     *            whether to serialized enums a Bean or name=value pair
     * @param excludeNullProperties
     *            enable/disable excluding of null properties
     * @param defaultDateFormat
     *            date format used to serialize dates
     * @param cacheBeanInfo
     * 			  Specifies whether to cache bean info in the JSONWriter
     * @return JSON string
     * @throws JSONException in case of error during serialize
     */
    public String serialize(Object object, Collection<Pattern> excludeProperties,
                                   Collection<Pattern> includeProperties, boolean ignoreHierarchy, boolean enumAsBean,
                                   boolean excludeNullProperties, String defaultDateFormat, boolean cacheBeanInfo) throws JSONException {
        writer.setIgnoreHierarchy(ignoreHierarchy);
        writer.setEnumAsBean(enumAsBean);
        writer.setDateFormatter(defaultDateFormat);
        writer.setCacheBeanInfo(cacheBeanInfo);
        return writer.write(object, excludeProperties, includeProperties, excludeNullProperties);
    }

    /**
     * Serializes an object into JSON to the given writer.
     *
     * @param writer
     *            Writer to serialize the object to
     * @param object
     *            object to be serialized
     * @throws IOException  in case of IO errors
     * @throws JSONException in case of error during serialize
     */
    public void serialize(Writer writer, Object object) throws IOException, JSONException {
        serialize(writer, object, CACHE_BEAN_INFO_DEFAULT);
    }
    
    /**
     * Serializes an object into JSON to the given writer.
     *
     * @param writer
     *            Writer to serialize the object to
     * @param object
     *            object to be serialized
     * @param cacheBeanInfo
     * 			  Specifies whether to cache bean info in the JSONWriter
     * @throws IOException  in case of IO errors
     * @throws JSONException in case of error during serialize
     */
    public void serialize(Writer writer, Object object, boolean cacheBeanInfo) throws IOException, JSONException {
        writer.write(serialize(object, cacheBeanInfo));
    }

    /**
     * Serializes an object into JSON to the given writer, excluding any
     * properties matching any of the regular expressions in the given
     * collection.
     *
     * @param writer
     *            Writer to serialize the object to
     * @param object
     *            object to be serialized
     * @param excludeProperties
     *            Patterns matching properties to ignore
     * @param includeProperties
     *            Patterns matching properties to include
     * @param excludeNullProperties
     *            enable/disable excluding of null properties
     * @throws IOException  in case of IO errors
     * @throws JSONException in case of error during serialize
     */
    public void serialize(Writer writer, Object object, Collection<Pattern> excludeProperties,
            Collection<Pattern> includeProperties, boolean excludeNullProperties) throws IOException,
            JSONException {
    	serialize(writer, object, excludeProperties, includeProperties, excludeNullProperties, CACHE_BEAN_INFO_DEFAULT);
    }
    
    /**
     * Serializes an object into JSON to the given writer, excluding any
     * properties matching any of the regular expressions in the given
     * collection.
     *
     * @param writer
     *            Writer to serialize the object to
     * @param object
     *            object to be serialized
     * @param excludeProperties
     *            Patterns matching properties to ignore
     * @param includeProperties
     *            Patterns matching properties to include
     * @param excludeNullProperties
     *            enable/disable excluding of null properties
     * @param cacheBeanInfo
     * 			  Specifies whether to cache bean info in the JSONWriter        
     * @throws IOException  in case of IO errors
     * @throws JSONException in case of error during serialize
     */
    public void serialize(Writer writer, Object object, Collection<Pattern> excludeProperties,
            Collection<Pattern> includeProperties, boolean excludeNullProperties, boolean cacheBeanInfo) 
            throws IOException, JSONException {
        writer.write(serialize(object, excludeProperties, includeProperties, true, excludeNullProperties, cacheBeanInfo));
    }

    /**
     * Deserializes a object from JSON
     *
     * @param json
     *            string in JSON
     * @return desrialized object
     * @throws JSONException in case of error during serialize
     */
    public static Object deserialize(String json) throws JSONException {
        JSONReader reader = new JSONReader();
        return reader.read(json);
    }

    /**
     * Deserializes a object from JSON
     *
     * @param reader
     *            Reader to read a JSON string from
     * @return deserialized object
     * @throws JSONException
     *             when IOException happens
     */
    public static Object deserialize(Reader reader) throws JSONException {
        // read content
        BufferedReader bufferReader = new BufferedReader(reader);
        String line;
        StringBuilder buffer = new StringBuilder();

        try {
            while ((line = bufferReader.readLine()) != null) {
                buffer.append(line);
            }
        } catch (IOException e) {
            throw new JSONException(e);
        }

        return deserialize(buffer.toString());
    }

    public static void writeJSONToResponse(SerializationParams serializationParams) throws IOException {
        StringBuilder stringBuilder = new StringBuilder();
        if (StringUtils.isNotBlank(serializationParams.getSerializedJSON()))
            stringBuilder.append(serializationParams.getSerializedJSON());

        if (StringUtils.isNotBlank(serializationParams.getWrapPrefix()))
            stringBuilder.insert(0, serializationParams.getWrapPrefix());
        else if (serializationParams.isWrapWithComments()) {
            stringBuilder.insert(0, "/* ");
            stringBuilder.append(" */");
        } else if (serializationParams.isPrefix())
            stringBuilder.insert(0, "{}&& ");

        if (StringUtils.isNotBlank(serializationParams.getWrapSuffix()))
            stringBuilder.append(serializationParams.getWrapSuffix());

        String json = stringBuilder.toString();

        LOG.debug("[JSON] {}", json);

        HttpServletResponse response = serializationParams.getResponse();

        // status or error code
        if (serializationParams.getStatusCode() > 0)
            response.setStatus(serializationParams.getStatusCode());
        else if (serializationParams.getErrorCode() > 0)
            response.sendError(serializationParams.getErrorCode());

        // content type
        response.setContentType(serializationParams.getContentType() + ";charset="
                + serializationParams.getEncoding());

        if (serializationParams.isNoCache()) {
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Expires", "0");
            response.setHeader("Pragma", "No-cache");
        }

        if (serializationParams.isGzip()) {
            response.addHeader("Content-Encoding", "gzip");
            GZIPOutputStream out = null;
            InputStream in = null;
            try {
                out = new GZIPOutputStream(response.getOutputStream());
                in = new ByteArrayInputStream(json.getBytes(serializationParams.getEncoding()));
                byte[] buf = new byte[1024];
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
            } finally {
                if (in != null)
                    in.close();
                if (out != null) {
                    out.finish();
                    out.close();
                }
            }

        } else {
            response.setContentLength(json.getBytes(serializationParams.getEncoding()).length);
            PrintWriter out = response.getWriter();
            out.print(json);
        }
    }

    public static Set<String> asSet(String commaDelim) {
        if ((commaDelim == null) || (commaDelim.trim().length() == 0))
            return null;
        return TextParseUtil.commaDelimitedStringToSet(commaDelim);
    }

    /**
     * List visible methods carrying the
     *
     * {@literal @}SMDMethod annotation
     *
     * @param clazz
     *            class
     * @param ignoreInterfaces
     *            if true, only the methods of the class are examined. If false,
     *            annotations on every interfaces' methods are examined.
     * @return array of SMD methods
     */
    @SuppressWarnings("unchecked")
    public static Method[] listSMDMethods(Class clazz, boolean ignoreInterfaces) {
        final List<Method> methods = new LinkedList<>();
        if (ignoreInterfaces) {
            Method[] SMDMethods = clazz.getMethods();
            Arrays.sort(SMDMethods, (a, b) -> a.toString().compareTo(b.toString()));
            for (Method method : SMDMethods) {
                SMDMethod smdMethodAnnotation = method.getAnnotation(SMDMethod.class);
                if (smdMethodAnnotation != null) {
                    methods.add(method);
                }
            }
        } else {
            // recurse the entire superclass/interface hierarchy and add in
            // order encountered
            JSONUtil.visitInterfaces(clazz, new JSONUtil.ClassVisitor() {
                public boolean visit(Class aClass) {
                    Method[] SMDMethods = aClass.getMethods();
                    Arrays.sort(SMDMethods, (a, b) -> a.toString().compareTo(b.toString()));
                    for (Method method : SMDMethods) {
                        SMDMethod smdMethodAnnotation = method.getAnnotation(SMDMethod.class);
                        if ((smdMethodAnnotation != null) && !methods.contains(method)) {
                            methods.add(method);
                        }
                    }
                    return true;
                }
            });
        }

        Method[] methodResult = new Method[methods.size()];
        return methods.toArray(methodResult);
    }

    /**
     * Realizes the visit(Class) method called by vistInterfaces for all
     * encountered classes/interfaces
     */
    public static interface ClassVisitor {

        /**
         * Called when a new interface/class is encountered
         *
         * @param aClass
         *            the encountered class/interface
         * @return true if the recursion should continue, false to stop
         *         recursion immediately
         */
        @SuppressWarnings("unchecked")
        boolean visit(Class aClass);
    }

    /**
     * Visit all the interfaces realized by the specified object, its
     * superclasses and its interfaces <br> Visitation is performed in the
     * following order: aClass aClass' interfaces the interface's superclasses
     * (interfaces) aClass' superclass superclass' interfaces superclass'
     * interface's superclasses (interfaces) super-superclass and so on <br> The
     * Object base class is base excluded. Classes/interfaces are only visited
     * once each
     *
     * @param aClass
     *            the class to start recursing upwards from
     * @param visitor
     *            this vistor is called for each class/interface encountered
     * @return true if all classes/interfaces were visited, false if it was
     *         exited early as specified by a ClassVisitor result
     */
    @SuppressWarnings("unchecked")
    public static boolean visitInterfaces(Class aClass, ClassVisitor visitor) {
        List<Class> classesVisited = new LinkedList<>();
        return visitUniqueInterfaces(aClass, visitor, classesVisited);
    }

    /*
     * Recursive method to visit all the interfaces of a class (and its
     * superclasses and super-interfaces) if they haven't already been visited.
     * <br> Always visits itself if it hasn't already been visited
     *
     * @param thisClass
     *            the current class to visit (if not already done so)
     * @param classesVisited
     *            classes already visited
     * @param visitor
     *            this vistor is called for each class/interface encountered
     * @return true if recursion can continue, false if it should be aborted
     */
    private static boolean visitUniqueInterfaces(Class thisClass, ClassVisitor visitor,
            List<Class> classesVisited) {
        boolean okayToContinue = true;

        if (!classesVisited.contains(thisClass)) {
            classesVisited.add(thisClass);
            okayToContinue = visitor.visit(thisClass);

            if (okayToContinue) {
                Class[] interfaces = thisClass.getInterfaces();
                int index = 0;
                while ((index < interfaces.length) && (okayToContinue)) {
                    okayToContinue = visitUniqueInterfaces(interfaces[index++], visitor, classesVisited);
                }

                if (okayToContinue) {
                    Class superClass = thisClass.getSuperclass();
                    if ((superClass != null) && (!Object.class.equals(superClass))) {
                        okayToContinue = visitUniqueInterfaces(superClass, visitor, classesVisited);
                    }
                }
            }
        }
        return okayToContinue;
    }

    public static boolean isGzipInRequest(HttpServletRequest request) {
        return StringUtils.contains(request.getHeader("Accept-Encoding"), "gzip");
    }

    public static final String REGEXP_PATTERN = "regexp";
    public static final String WILDCARD_PATTERN = "wildcard";
    /* package */ static final String SPLIT_PATTERN = "split";
    /* package */ static final String JOIN_STRING = "join";
    /* package */ static final String ARRAY_BEGIN_STRING = "array-begin";
    /* package */ static final String ARRAY_END_STRING = "array-end";

    /* package */ static Map<String, Map<String, String>> getIncludePatternData()
    {
        Map<String, Map<String, String>> includePatternData = new HashMap<>();

        Map<String, String> data = new HashMap<>();
        data.put(REGEXP_PATTERN, "\\\\\\.");
        data.put(WILDCARD_PATTERN, "\\.");
        includePatternData.put(SPLIT_PATTERN, data);

        data = new HashMap<>();
        data.put(REGEXP_PATTERN, "\\.");
        data.put(WILDCARD_PATTERN, ".");
        includePatternData.put(JOIN_STRING, data);

        data = new HashMap<>();
        data.put(REGEXP_PATTERN, "\\[");
        data.put(WILDCARD_PATTERN, "[");
        includePatternData.put(ARRAY_BEGIN_STRING, data);

        data = new HashMap<>();
        data.put(REGEXP_PATTERN, "\\]");
        data.put(WILDCARD_PATTERN, "]");
        includePatternData.put(ARRAY_END_STRING, data);

        return includePatternData;
    }

    private static final Map<String, Map<String, String>> defaultIncludePatternData = getIncludePatternData();

    public static List<Pattern> processIncludePatterns(Set<String> includePatterns, String type) {
        return processIncludePatterns(includePatterns, type, defaultIncludePatternData);
    }

    /* package */ static List<Pattern> processIncludePatterns(Set<String> includePatterns, String type, Map<String, Map<String, String>> includePatternData) {
        if (includePatterns != null) {
            List<Pattern> results = new ArrayList<>(includePatterns.size());
            Map<String, String> existingPatterns = new HashMap<>();
            for (String pattern : includePatterns) {
                processPattern(results, existingPatterns, pattern, type, includePatternData);
            }
            return results;
        } else {
            return null;
        }
    }

    private static void processPattern(List<Pattern> results, Map<String, String> existingPatterns, String pattern, String type, Map<String, Map<String, String>> includePatternData) {
        // Compile a pattern for each *unique* "level" of the object
        // hierarchy specified in the regex.
        String[] patternPieces = pattern.split(includePatternData.get(SPLIT_PATTERN).get(type));

        String patternExpr = "";
        for (String patternPiece : patternPieces) {
            patternExpr = processPatternPiece(results, existingPatterns, patternExpr, patternPiece, type, includePatternData);
        }
    }

    private static String processPatternPiece(List<Pattern> results, Map<String, String> existingPatterns, String patternExpr, String patternPiece, String type, Map<String, Map<String, String>> includePatternData) {
        if (patternExpr.length() > 0) {
            patternExpr += includePatternData.get(JOIN_STRING).get(type);
        }
        patternExpr += patternPiece;

        // Check for duplicate patterns so that there is no overlap.
        if (!existingPatterns.containsKey(patternExpr)) {
            existingPatterns.put(patternExpr, patternExpr);
            if (isIndexedProperty(patternPiece, type, includePatternData)) {
                addPattern(results, patternExpr.substring(0, patternExpr.lastIndexOf(includePatternData.get(ARRAY_BEGIN_STRING).get(type))), type);
            }
            addPattern(results, patternExpr, type);
        }
        return patternExpr;
    }

    /*
     * Add a pattern that does not have the indexed property matching (ie. list\[\d+\] becomes list).
     */
    private static boolean isIndexedProperty(String patternPiece, String type, Map<String, Map<String, String>> includePatternData) {
        return patternPiece.endsWith(includePatternData.get(ARRAY_END_STRING).get(type));
    }

    private static void addPattern(List<Pattern> results, String pattern, String type) {
        results.add(REGEXP_PATTERN.equals(type) ? Pattern.compile(pattern) : WildcardUtil.compileWildcardPattern(pattern));
        if (LOG.isTraceEnabled()) {
            LOG.trace("Adding include {} expression: {}", (REGEXP_PATTERN.equals(type) ? "property" : "wildcard"), pattern);
        }
    }

}
