/*
 * 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 flex.messaging.util;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

/**
 *
 */
public class StringUtils {
    /**
     * The String to use for an OS specific line separator.
     */
    public static final String NEWLINE = System.getProperty("line.separator");

    public static String substitute(String str, String from, String to) {
        if (from == null || from.equals("") || to == null)
            return str;

        int index = str.indexOf(from);

        if (index == -1)
            return str;

        StringBuffer buf = new StringBuffer(str.length());
        int lastIndex = 0;

        while (index != -1) {
            buf.append(str.substring(lastIndex, index));
            buf.append(to);
            lastIndex = index + from.length();
            index = str.indexOf(from, lastIndex);
        }

        // add in last chunk
        buf.append(str.substring(lastIndex));

        return buf.toString();
    }

    public static boolean findMatchWithWildcard(char[] src, char[] pat) {
        if (src == null || pat == null)
            return false;

        // we consider an empty pattern to be a don't-match-anything pattern
        if (pat.length == 0)
            return false;

        if (src.length == 0)
            return (pat.length == 0 || (pat.length == 1 && (pat[0] == '*' || pat[0] == '?')));

        boolean star = false;

        int srcLen = src.length;
        int patLen = pat.length;
        int srcIdx = 0;
        int patIdx = 0;

        for (; srcIdx < srcLen; srcIdx++) {
            if (patIdx == patLen) {
                if (patLen < (srcLen - srcIdx))
                    patIdx = 0; //Start the search again
                else
                    return false;
            }

            char s = src[srcIdx];
            char m = pat[patIdx];

            switch (m) {
                case '*':
                    // star on the end
                    if (patIdx == pat.length - 1)
                        return true;
                    star = true;
                    ++patIdx;
                    break;

                case '?':
                    ++patIdx;
                    break;

                default:
                    if (s != m) {
                        if (!star) {
                            if (patLen < (srcLen - srcIdx))
                                patIdx = 0; //Start the search again
                            else
                                return false;
                        }
                    } else {
                        star = false;
                        ++patIdx;
                    }
                    break;
            }
        }

        if (patIdx < patLen) {
            //read off the rest of the pattern and make sure it's all wildcard
            for (; patIdx < patLen; patLen++) {
                if (pat[patIdx] != '*') {
                    return false;
                }
            }
            return true;
        }


        return !star;
    }

    /**
     * Returns a prettified version of the XML, with indentations and
     * linefeeds.  Returns the original string if there was an error.
     *
     * @param xml the xml string
     * @return String the prettified xml string
     */
    public static String prettifyXML(String xml) {
        String result = xml;
        try {
            StringReader reader = new StringReader(xml);
            StringWriter writer = new StringWriter();
            Transformer transformer =
                    TransformerFactory.newInstance().newTransformer();
            transformer.setOutputProperty(OutputKeys.METHOD, "xml");
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.transform
                    (new StreamSource(reader), new StreamResult(writer));
            writer.close();

            result = writer.toString();
        } catch (TransformerFactoryConfigurationError error) {
            // Ignore.
        } catch (TransformerException error) {
            // Ignore.
        } catch (IOException error) {
            // Ignore.
        }
        return result;
    }

    /**
     * Returns a prettified version of the string, or the original
     * string if the operation is not possible.
     *
     * @param string the string to check
     * @return String the prettified string
     */
    public static String prettifyString(String string) {
        String result = string;
        if (string.startsWith("<?xml")) {
            result = prettifyXML(string);
        }
        return result;
    }

    /**
     * Returns true if a string is null or empty.
     *
     * @param string the String to check
     * @return boolean true if the string is an empty string
     */
    public static boolean isEmpty(String string) {
        return string == null || string.length() == 0;
    }
}

