/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed 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.xmlbeans.impl.common;

import javax.xml.namespace.QName;
import org.apache.xmlbeans.xml.stream.XMLName;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
import java.io.UnsupportedEncodingException;

import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaField;

public class QNameHelper
{
    private static final Map WELL_KNOWN_PREFIXES = buildWKP();

    public static XMLName getXMLName(QName qname)
    {
        if (qname == null)
            return null;

        return XMLNameHelper.forLNS( qname.getLocalPart(), qname.getNamespaceURI() );
    }

    public static QName forLNS(String localname, String uri)
    {
        if (uri == null)
            uri = "";
        return new QName(uri, localname);
    }

    public static QName forLN(String localname)
    {
        return new QName("", localname);
    }

    public static QName forPretty(String pretty, int offset)
    {
        int at = pretty.indexOf('@', offset);
        if (at < 0)
            return new QName("", pretty.substring(offset));
        return new QName(pretty.substring(at + 1), pretty.substring(offset, at));
    }

    public static String pretty(QName name)
    {
        if (name == null)
            return "null";

        if (name.getNamespaceURI() == null || name.getNamespaceURI().length() == 0)
            return name.getLocalPart();

        return name.getLocalPart() + "@" + name.getNamespaceURI();
    }

    private static final char[] hexdigits = new char[]
        {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

    private static boolean isSafe(int c)
    {
        if (c >= 'a' && c <= 'z')
            return true;
        if (c >= 'A' && c <= 'Z')
            return true;
        if (c >= '0' && c <= '9')
            return true;
        return false;
    }

    // This produces a string which is a safe filename from the given string s.
    // To make it a safe filename, the following two transformations are applied:
    //
    // 1. First all non-ascii-alphanumeric characters are escaped using
    //    their UTF8 byte sequence, in the form _xx_xx_xx, for example,
    //    "Hello_20There" for "Hello There".  (Obviously, a single unicode
    //    character may expand into as many as three escape patterns.)
    //    If the resulting string is 64 characters or fewer, that's the result.
    //
    // 2. If the resulting string is longer than 64 characters, then it is
    //    discarded.  Instead, the SHA1 algorithm is run on the original
    //    string's UTF8 representation, and then the resulting 20-byte message
    //    digest is turned into a 40-character hex string; then "URI_SHA_1_" is
    //    prepended.
    //
    // The reason for the "shortening" is to avoid filenames longer than about
    // 256 characters, which are prohibited on Windows NT.

    public static final int MAX_NAME_LENGTH = 64;

    public static String hexsafe(String s)
    {
        StringBuffer result = new StringBuffer();
        for (int i = 0; i < s.length(); i++)
        {
            char ch = s.charAt(i);
            if (isSafe(ch))
            {
                result.append(ch);
            }
            else
            {
                byte[] utf8 = null;
                try
                {
                    utf8 = s.substring(i, i + 1).getBytes("UTF-8");
                    for (int j = 0; j < utf8.length; j++)
                    {
                        result.append('_');
                        result.append(hexdigits[(utf8[j] >> 4) & 0xF]);
                        result.append(hexdigits[utf8[j] & 0xF]);
                    }
                }
                catch(UnsupportedEncodingException uee)
                {
                    // should never happen - UTF-8 i always supported
                    result.append("_BAD_UTF8_CHAR");
                }
            }
        }

        // short enough? Done!
        if (result.length() <= MAX_NAME_LENGTH)
            return result.toString();

        // too long? use SHA1
        try
        {
            MessageDigest md = MessageDigest.getInstance("SHA");
            byte[] inputBytes = null;
            try
            {
                inputBytes = s.getBytes("UTF-8");
            }
            catch(UnsupportedEncodingException uee)
            {
                // should never happen - UTF-8 is always supported
                inputBytes = new byte[0];
            }
            byte[] digest = md.digest(inputBytes);
            assert(digest.length == 20); // SHA1 160 bits == 20 bytes
            result = new StringBuffer("URI_SHA_1_");
            for (int j = 0; j < digest.length; j++)
            {
                result.append(hexdigits[(digest[j] >> 4) & 0xF]);
                result.append(hexdigits[digest[j] & 0xF]);
            }
            return result.toString();
        }
        catch (NoSuchAlgorithmException e)
        {
            throw new IllegalStateException("Using in a JDK without an SHA implementation");
        }
    }

    public static String hexsafedir(QName name)
    {
        if (name.getNamespaceURI() == null || name.getNamespaceURI().length() == 0)
            return "_nons/" + hexsafe(name.getLocalPart());
        return hexsafe(name.getNamespaceURI()) + "/" + hexsafe(name.getLocalPart());
    }

    private static Map buildWKP()
    {
        Map result = new HashMap();
        result.put("http://www.w3.org/XML/1998/namespace", "xml");
        result.put("http://www.w3.org/2001/XMLSchema", "xs");
        result.put("http://www.w3.org/2001/XMLSchema-instance", "xsi");
        result.put("http://schemas.xmlsoap.org/wsdl/", "wsdl");
        result.put("http://schemas.xmlsoap.org/soap/encoding/", "soapenc");
        result.put("http://schemas.xmlsoap.org/soap/envelope/", "soapenv");
        return Collections.unmodifiableMap(result);
    }

    public static String readable(SchemaType sType)
    {
        return readable(sType, WELL_KNOWN_PREFIXES);
    }

    public static String readable(SchemaType sType, Map nsPrefix)
    {
        if (sType.getName() != null)
        {
            return readable(sType.getName(), nsPrefix);
        }

        if (sType.isAttributeType())
        {
            return "attribute type " + readable(sType.getAttributeTypeAttributeName(), nsPrefix);
        }

        if (sType.isDocumentType())
        {
            return "document type " + readable(sType.getDocumentElementName(), nsPrefix);
        }

        if (sType.isNoType() || sType.getOuterType() == null)
        {
            return "invalid type";
        }

        SchemaType outerType = sType.getOuterType();
        SchemaField container = sType.getContainerField();

        if (outerType.isAttributeType())
        {
            return "type of attribute " + readable(container.getName(), nsPrefix);
        }
        else if (outerType.isDocumentType())
        {
            return "type of element " + readable(container.getName(), nsPrefix);
        }

        if (container != null)
        {
            if (container.isAttribute())
            {
                return "type of " + container.getName().getLocalPart() + " attribute in " + readable(outerType, nsPrefix);
            }
            else
            {
                return "type of " + container.getName().getLocalPart() + " element in " + readable(outerType, nsPrefix);
            }
        }

        if (outerType.getBaseType() == sType)
            return "base type of " + readable(outerType, nsPrefix);
        else if (outerType.getSimpleVariety() == SchemaType.LIST)
            return "item type of " + readable(outerType, nsPrefix);
        else if (outerType.getSimpleVariety() == SchemaType.UNION)
            return "member type " + sType.getAnonymousUnionMemberOrdinal() + " of " + readable(outerType, nsPrefix);
        else
            return "inner type in " + readable(outerType, nsPrefix);
    }

    public static String readable(QName name)
    {
        return readable(name, WELL_KNOWN_PREFIXES);
    }

    public static String readable(QName name, Map prefixes)
    {
        if (name.getNamespaceURI().length() == 0)
            return name.getLocalPart();
        String prefix = (String)prefixes.get(name.getNamespaceURI());
        if (prefix != null)
            return prefix + ":" + name.getLocalPart();
        return name.getLocalPart() + " in namespace " + name.getNamespaceURI();
    }

    public static String suggestPrefix(String namespace)
    {
        String result = (String)WELL_KNOWN_PREFIXES.get(namespace);
        if (result != null)
            return result;

        int len = namespace.length();
        int i = namespace.lastIndexOf('/');
        if (i > 0 && i == namespace.length() - 1)
        {
            len = i;
            i = namespace.lastIndexOf('/', i - 1);
        }

        i += 1; // skip '/', also covers -1 case.

        if (namespace.startsWith("www.", i))
        {
            i += 4; // "www.".length()
        }

        while (i < len)
        {
            if (XMLChar.isNCNameStart(namespace.charAt(i)))
                break;
            i += 1;
        }

        for (int end = i + 1; end < len; end += 1)
        {
            if (!XMLChar.isNCName(namespace.charAt(end)) || !Character.isLetterOrDigit(namespace.charAt(end)))
            {
                len = end;
                break;
            }
        }

        // prefixes starting with "xml" are forbidden, so change "xmls" -> "xs"
        if (namespace.length() >= i + 3 && startsWithXml(namespace, i))
        {
            if (namespace.length() >= i + 4)
                return "x" + Character.toLowerCase(namespace.charAt(i + 3));
            return "ns";
        }

        if (len - i > 4) // four or less? leave it.
        {
            if (isVowel(namespace.charAt(i + 2)) && !isVowel(namespace.charAt(i + 3)))
                len = i + 4;
            else
                len = i + 3; // more than four? truncate to 3.
        }

        int n;

        if (len - i == 0)
            return "ns";

        return namespace.substring(i, len).toLowerCase();
    }

    private static boolean startsWithXml(String s, int i)
    {
        if (s.length() < i + 3)
            return false;

        if (s.charAt(i) != 'X' && s.charAt(i) != 'x')
            return false;
        if (s.charAt(i + 1) != 'M' && s.charAt(i + 1) != 'm')
            return false;
        if (s.charAt(i + 2) != 'L' && s.charAt(i + 2) != 'l')
            return false;

        return true;
    }

    private static boolean isVowel(char ch)
    {
        switch (ch)
        {
            case 'a':
            case 'e':
            case 'i':
            case 'o':
            case 'u':
            case 'A':
            case 'E':
            case 'I':
            case 'O':
            case 'U':
                return true;
            default:
                return false;
        }
    }

    public static String namespace(SchemaType sType)
    {
        while (sType != null)
        {
            if (sType.getName() != null)
                return sType.getName().getNamespaceURI();
            if (sType.getContainerField() != null && sType.getContainerField().getName().getNamespaceURI().length() > 0)
                return sType.getContainerField().getName().getNamespaceURI();
            sType = sType.getOuterType();
        }
        return "";
    }
}
