/**
 * 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.xml.security.utils;

import java.io.IOException;
import java.io.StringReader;

public class RFC2253Parser {

    /**
     * Method rfc2253toXMLdsig
     *
     * @param dn
     * @return normalized string
     */
    public static String rfc2253toXMLdsig(String dn) {
        // Transform from RFC1779 to RFC2253
        String normalized = normalize(dn, true);

        return rfctoXML(normalized);
    }

    /**
     * Method xmldsigtoRFC2253
     *
     * @param dn
     * @return normalized string
     */
    public static String xmldsigtoRFC2253(String dn) {
        // Transform from RFC1779 to RFC2253
        String normalized = normalize(dn, false);

        return xmltoRFC(normalized);
    }

    /**
     * Method normalize
     *
     * @param dn
     * @return normalized string
     */
    public static String normalize(String dn) {
        return normalize(dn, true);
    }

    /**
     * Method normalize
     *
     * @param dn
     * @param toXml
     * @return normalized string
     */
    public static String normalize(String dn, boolean toXml) {
        //if empty string
        if (dn == null || dn.equals("")) {
            return "";
        }

        try {
            String DN = semicolonToComma(dn);
            StringBuilder sb = new StringBuilder();
            int i = 0;
            int l = 0;
            int k;

            //for name component
            for (int j = 0; (k = DN.indexOf(',', j)) >= 0; j = k + 1) {
                l += countQuotes(DN, j, k);

                if (k > 0 && DN.charAt(k - 1) != '\\' && (l % 2) == 0) {
                    sb.append(parseRDN(DN.substring(i, k).trim(), toXml)).append(",");

                    i = k + 1;
                    l = 0;
                }
            }

            sb.append(parseRDN(trim(DN.substring(i)), toXml));

            return sb.toString();
        } catch (IOException ex) {
            return dn;
        }
    }

    /**
     * Method parseRDN
     *
     * @param str
     * @param toXml
     * @return normalized string
     * @throws IOException
     */
    static String parseRDN(String str, boolean toXml) throws IOException {
        StringBuilder sb = new StringBuilder();
        int i = 0;
        int l = 0;
        int k;

        for (int j = 0; (k = str.indexOf('+', j)) >= 0; j = k + 1) {
            l += countQuotes(str, j, k);

            if (k > 0 && str.charAt(k - 1) != '\\' && (l % 2) == 0) {
                sb.append(parseATAV(trim(str.substring(i, k)), toXml)).append("+");

                i = k + 1;
                l = 0;
            }
        }

        sb.append(parseATAV(trim(str.substring(i)), toXml));

        return sb.toString();
    }

    /**
     * Method parseATAV
     *
     * @param str
     * @param toXml
     * @return normalized string
     * @throws IOException
     */
    static String parseATAV(String str, boolean toXml) throws IOException {
        int i = str.indexOf('=');

        if (i == -1 || i > 0 && str.charAt(i - 1) == '\\') {
            return str;
        }
        String attrType = normalizeAT(str.substring(0, i));
        // only normalize if value is a String
        String attrValue = null;
        if (attrType.charAt(0) >= '0' && attrType.charAt(0) <= '9') {
            attrValue = str.substring(i + 1);
        } else {
            attrValue = normalizeV(str.substring(i + 1), toXml);
        }

        return attrType + "=" + attrValue;

    }

    /**
     * Method normalizeAT
     *
     * @param str
     * @return normalized string
     */
    static String normalizeAT(String str) {

        String at = str.toUpperCase().trim();

        if (at.startsWith("OID")) {
            at = at.substring(3);
        }

        return at;
    }

    /**
     * Method normalizeV
     *
     * @param str
     * @param toXml
     * @return normalized string
     * @throws IOException
     */
    static String normalizeV(String str, boolean toXml) throws IOException {
        String value = trim(str);

        if (value.startsWith("\"")) {
            StringBuilder sb = new StringBuilder();
            StringReader sr = new StringReader(value.substring(1, value.length() - 1));
            int i = 0;
            char c;

            while ((i = sr.read()) > -1) {
                c = (char) i;

                //the following char is defined at 4.Relationship with RFC1779 and LDAPv2 inrfc2253
                if (c == ',' || c == '=' || c == '+' || c == '<'
                    || c == '>' || c == '#' || c == ';') {
                    sb.append('\\');
                }

                sb.append(c);
            }

            value = trim(sb.toString());
        }

        if (toXml) {
            if (value.startsWith("#")) {
                value = '\\' + value;
            }
        } else {
            if (value.startsWith("\\#")) {
                value = value.substring(1);
            }
        }

        return value;
    }

    /**
     * Method rfctoXML
     *
     * @param string
     * @return normalized string
     */
    static String rfctoXML(String string) {
        try {
            String s = changeLess32toXML(string);

            return changeWStoXML(s);
        } catch (Exception e) {
            return string;
        }
    }

    /**
     * Method xmltoRFC
     *
     * @param string
     * @return normalized string
     */
    static String xmltoRFC(String string) {
        try {
            String s = changeLess32toRFC(string);

            return changeWStoRFC(s);
        } catch (Exception e) {
            return string;
        }
    }

    /**
     * Method changeLess32toRFC
     *
     * @param string
     * @return normalized string
     * @throws IOException
     */
    static String changeLess32toRFC(String string) throws IOException {
        StringBuilder sb = new StringBuilder();
        StringReader sr = new StringReader(string);
        int i = 0;
        char c;

        while ((i = sr.read()) > -1) {
            c = (char) i;

            if (c == '\\') {
                sb.append(c);

                char c1 = (char) sr.read();
                char c2 = (char) sr.read();

                //65 (A) 97 (a)
                if ((c1 >= 48 && c1 <= 57 || c1 >= 65 && c1 <= 70 || c1 >= 97 && c1 <= 102)
                    && (c2 >= 48 && c2 <= 57
                        || c2 >= 65 && c2 <= 70
                        || c2 >= 97 && c2 <= 102)) {
                    char ch = (char) Byte.parseByte("" + c1 + c2, 16);

                    sb.append(ch);
                } else {
                    sb.append(c1);
                    sb.append(c2);
                }
            } else {
                sb.append(c);
            }
        }

        return sb.toString();
    }

    /**
     * Method changeLess32toXML
     *
     * @param string
     * @return normalized string
     * @throws IOException
     */
    static String changeLess32toXML(String string) throws IOException {
        StringBuilder sb = new StringBuilder();
        StringReader sr = new StringReader(string);
        int i = 0;

        while ((i = sr.read()) > -1) {
            if (i < 32) {
                sb.append('\\');
                sb.append(Integer.toHexString(i));
            } else {
                sb.append((char) i);
            }
        }

        return sb.toString();
    }

    /**
     * Method changeWStoXML
     *
     * @param string
     * @return normalized string
     * @throws IOException
     */
    static String changeWStoXML(String string) throws IOException {
        StringBuilder sb = new StringBuilder();
        StringReader sr = new StringReader(string);
        int i = 0;
        char c;

        while ((i = sr.read()) > -1) {
            c = (char) i;

            if (c == '\\') {
                char c1 = (char) sr.read();

                if (c1 == ' ') {
                    sb.append('\\');

                    String s = "20";

                    sb.append(s);
                } else {
                    sb.append('\\');
                    sb.append(c1);
                }
            } else {
                sb.append(c);
            }
        }

        return sb.toString();
    }

    /**
     * Method changeWStoRFC
     *
     * @param string
     * @return normalized string
     */
    static String changeWStoRFC(String string) {
        StringBuilder sb = new StringBuilder();
        int i = 0;
        int k;

        for (int j = 0; (k = string.indexOf("\\20", j)) >= 0; j = k + 3) {
            sb.append(trim(string.substring(i, k))).append("\\ ");

            i = k + 3;
        }

        sb.append(string.substring(i));

        return sb.toString();
    }

    /**
     * Method semicolonToComma
     *
     * @param str
     * @return normalized string
     */
    static String semicolonToComma(String str) {
        return removeWSandReplace(str, ";", ",");
    }

    /**
     * Method removeWhiteSpace
     *
     * @param str
     * @param symbol
     * @return normalized string
     */
    static String removeWhiteSpace(String str, String symbol) {
        return removeWSandReplace(str, symbol, symbol);
    }

    /**
     * Method removeWSandReplace
     *
     * @param str
     * @param symbol
     * @param replace
     * @return normalized string
     */
    static String removeWSandReplace(String str, String symbol, String replace) {
        StringBuilder sb = new StringBuilder();
        int i = 0;
        int l = 0;
        int k;

        for (int j = 0; (k = str.indexOf(symbol, j)) >= 0; j = k + 1) {
            l += countQuotes(str, j, k);

            if (k > 0 && str.charAt(k - 1) != '\\' && (l % 2) == 0) {
                sb.append(trim(str.substring(i, k))).append(replace);

                i = k + 1;
                l = 0;
            }
        }

        sb.append(trim(str.substring(i)));

        return sb.toString();
    }

    /**
     * Returns the number of Quotation from i to j
     *
     * @param s
     * @param i
     * @param j
     * @return number of quotes
     */
    private static int countQuotes(String s, int i, int j) {
        int k = 0;

        for (int l = i; l < j; l++) {
            if (s.charAt(l) == '"') {
                k++;
            }
        }

        return k;
    }

    //only for the end of a space character occurring at the end of the string from rfc2253

    /**
     * Method trim
     *
     * @param str
     * @return the string
     */
    static String trim(String str) {

        String trimed = str.trim();
        int i = str.indexOf(trimed) + trimed.length();

        if (str.length() > i && trimed.endsWith("\\")
            && !trimed.endsWith("\\\\") && str.charAt(i) == ' ') {
            trimed = trimed + " ";
        }

        return trimed;
    }

}
