/*
 * 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.commons.scxml2.io;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;

import org.apache.commons.io.IOUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

/**
 * The ContentParser provides utility methods for cleaning content strings and parsing them into "raw" content model Objects
 */
public class ContentParser {

    public static final ContentParser DEFAULT_PARSER = new ContentParser();

    /**
     * Jackson JSON ObjectMapper
     */
    private ObjectMapper jsonObjectMapper;

    /**
     * Default constructor initializing a Jackson ObjectMapper allowing embedded comments, including YAML style
     */
    public ContentParser() {
        this.jsonObjectMapper = new ObjectMapper();
        jsonObjectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
        jsonObjectMapper.configure(JsonParser.Feature.ALLOW_YAML_COMMENTS, true);
    }

    /**
     * Constructor with a custom configured Jackson ObjectMapper
     * @param jsonObjectMapper custom configured Jackson ObjectMapper
     */
    public ContentParser(final ObjectMapper jsonObjectMapper) {
        this.jsonObjectMapper = jsonObjectMapper;
    }

    /**
     * Trim pre/post-fixed whitespace from content string
     * @param content content to trim
     * @return trimmed content
     */
    public static String trimContent(final String content) {
        if (content != null) {
            int start = 0;
            int length = content.length();
            while (start < length && isWhiteSpace(content.charAt(start))) {
                start++;
            }
            while (length > start && isWhiteSpace(content.charAt(length - 1))) {
                length--;
            }
            if (start == length) {
                return "";
            }
            return content.substring(start, length);
        }
        return null;
    }

    /**
     * Space normalize content string, trimming pre/post-fixed whitespace and collapsing embedded whitespaces to
     * single space.
     * @param content content to space-normalize
     * @return space-normalized content
     */
    public static String spaceNormalizeContent(final String content) {
        if (content != null) {
            int index = 0;
            int length = content.length();
            StringBuilder buffer = new StringBuilder(length);
            boolean whiteSpace = false;
            while (index < length) {
                if (isWhiteSpace(content.charAt(index))) {
                    if (!whiteSpace && buffer.length() > 0) {
                        buffer.append(' ');
                        whiteSpace = true;
                    }
                }
                else {
                    buffer.append(content.charAt(index));
                    whiteSpace = false;
                }
                index++;
            }
            if (whiteSpace) {
                buffer.setLength(buffer.length()-1);
            }
            return buffer.toString();
        }
        return null;
    }

    /**
     * Check if a character is whitespace (space, tab, newline, cr) or not
     * @param c character to check
     * @return true if character is whitespace
     */
    public static boolean isWhiteSpace(final char c) {
        return c==' ' || c=='\n' || c=='\t' || c=='\r';
    }

    /**
     * Check if content starts with JSON object '{' or array '[' marker
     * @param content text to check
     * @return true if content start with '{' or '[' character
     */
    public static boolean hasJsonSignature(final String content) {
        final char c = content.length() > 0 ? content.charAt(0) : 0;
        return c == '{' || c == '[';
    }

    /**
     * Check if content indicates its an XML document
     * @param content content to check
     * @return true if content indicates its an XML document
     */
    public static boolean hasXmlSignature(final String content) {
        return content != null && content.startsWith("<?xml ");
    }

    /**
     * Parse and map JSON string to 'raw' Java Objects: object -> LinkedHashMap, array -> ArrayList
     * @param jsonString JSON string to parse
     * @return 'raw' mapped Java Object for JSON string
     * @throws IOException In case of parsing exceptions
     */
    public Object parseJson(final String jsonString) throws IOException {
        return jsonObjectMapper.readValue(jsonString, Object.class);
    }

    /**
     * Parse an XML String and return the document element
     * @param xmlString XML String to parse
     * @return document element
     * @throws IOException
     */
    public Node parseXml(final String xmlString) throws IOException {
        Document doc = null;
        try {
            doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlString);
        } catch (SAXException e) {
            throw new IOException(e);
        } catch (ParserConfigurationException e) {
            throw new IOException(e);
        }
        return doc != null ? doc.getDocumentElement() : null;
    }

    /**
     * Parse a string into a content object, following the SCXML rules as specified for the ECMAscript (section B.2.1) Data Model
     * <ul>
     *   <li>if the content can be interpreted as JSON, it will be parsed as JSON into an 'raw' object model</li>
     *   <li>if the content can be interpreted as XML, it will be parsed into a XML DOM element</li>
     *   <li>otherwise the content will be treated (cleaned) as a space-normalized string literal</li>
     * </ul>
     * @param content the content to parse
     * @return the parsed content object
     * @throws IOException In case of parsing exceptions
     */
    public Object parseContent(final String content) throws IOException {
        if (content != null) {
            String src = trimContent(content);
            if (hasJsonSignature(src)) {
                return parseJson(src);
            }
            else if (hasXmlSignature(src)) {
                return parseXml(src);
            }
            return spaceNormalizeContent(src);
        }
        return null;
    }

    /**
     * Load a resource (URL) as an UTF-8 encoded content string to be parsed into a content object through {@link #parseContent(String)}
     * @param resourceURL Resource URL to load content from
     * @return the parsed content object
     * @throws IOException In case of loading or parsing exceptions
     */
    public Object parseResource(final String resourceURL) throws IOException {
        InputStream in = null;
        try {
            in = new URL(resourceURL).openStream();
            String content = IOUtils.toString(in, "UTF-8");
            return parseContent(content);
        }
        finally {
            IOUtils.closeQuietly(in);
        }
    }
}
