/*
 * 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.openjpa.lib.identifier;

import java.util.ArrayList;
import java.util.Locale;

import org.apache.openjpa.lib.conf.Configurable;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.StringUtil;

/**
 * Implementation class for the base identifier impl.
 *
 */
public class IdentifierUtilImpl implements IdentifierUtil, Configurable {

    private static final Localizer _loc = Localizer.forPackage
        (IdentifierUtilImpl.class);

    private IdentifierConfiguration _config = null;

    public IdentifierUtilImpl() {

    }

    public IdentifierUtilImpl(IdentifierConfiguration config) {
        _config = config;
    }

    @Override
    public void setIdentifierConfiguration(IdentifierConfiguration config) {
        _config = config;
    }

    @Override
    public IdentifierConfiguration getIdentifierConfiguration() {
        return _config;
    }

    @Override
    public String combineNames(String rule, String name1, String name2) {
        return combineNames(getNamingRule(rule), name1, name2);
    }

    @Override
    public String combineNames(String rule, String[] names) {
        return combineNames(getNamingRule(rule), names);
    }

    public String combineNames(IdentifierConfiguration config, String rule, String[] names) {
        return combineNames(config, getNamingRule(rule), names);
    }

    @Override
    public String combineNames(IdentifierRule rule,
        IdentifierRule[] rules, String[] names) {
        return combineNames(_config, rule, rules, names);
    }

    public String combineNames(IdentifierConfiguration config, IdentifierRule rule,
        IdentifierRule[] rules, String[] names) {
        boolean delimited = false;
        String combined = null;
        for (int i = 0; i < names.length; i++) {
            String name = names[i];
            if (isDelimited(rules[i], name)) {
                delimited = true;
                name = removeDelimiters(config, rules[i], name);
            }
            if (i == 0) {
                combined = name;
            }
            else {
                combined = combined + config.getIdentifierConcatenator() + name;
            }
        }

        if (delimited) {
            combined = delimit(config, rule, combined);
        }

        return combined;
    }

    public String combineNames(IdentifierConfiguration config, IdentifierRule rule, String name1, String name2) {
        boolean delimit = false;
        if (isDelimited(rule, name1)) {
            name1 = removeDelimiters(config, rule, name1);
            delimit = true;
        }
        if (isDelimited(rule, name2)) {
            name2 = removeDelimiters(config, rule, name2);
            delimit = true;
        }
        String name = name1 + config.getIdentifierConcatenator() + name2;
        return delimit(config, rule, name, delimit);
    }

    public String combineNames(IdentifierConfiguration config, IdentifierRule namingRule, String[] names) {
        boolean delimited = false;
        String combined = null;
        for (int i = 0; i < names.length; i++) {
            String name = names[i];
            if (isDelimited(config, namingRule, name)) {
                delimited = true;
                name = removeDelimiters(config, namingRule, name);
            }
            if (i == 0) {
                combined = name;
            }
            else {
                combined = combined + config.getIdentifierConcatenator() + name;
            }
        }
        if (delimited) {
            combined = delimit(config, namingRule, combined);
        }

        return combined;
    }

    @Override
    public String appendNames(IdentifierRule rule, String name1, String name2) {
        if (isDelimited(rule, name1)) {
            name1 = removeDelimiters(rule, name1);
        }
        if (isDelimited(rule, name2)) {
            name2 = removeDelimiters(rule, name2);
        }
        if (name1 == null) {
            name1 = IdentifierUtil.EMPTY;
        }
        if (name2 == null) {
            name2 = IdentifierUtil.EMPTY;
        }
        String name = name1 + name2;
        return delimit(rule, name);
    }

    /**
     * Joins multiple names together using the standard delimiting rules
     * ex. ( {"s", "t", "c"} --> "s"."t"."c" }
     */
    @Override
    public String joinNames(IdentifierRule[] rules, String[] names) {

        if (names == null || names.length == 0) {
            return null;
        }
        StringBuilder combinedName = new StringBuilder();
        for (int i = 0; i < names.length; i++) {
            combinedName.append(delimit(rules[i], names[i]));
            if (i < (names.length -1)) {
                combinedName.append(_config.getIdentifierDelimiter());
            }
        }
        return combinedName.toString();
    }

    @Override
    public String joinNames(String rule, String[] names) {
        return joinNames(_config, getNamingRule(rule), names, _config.getIdentifierDelimiter());
    }

    @Override
    public String joinNames(IdentifierRule rule, String[] names) {
        return joinNames(_config, rule, names, _config.getIdentifierDelimiter());
    }

    @Override
    public String joinNames(IdentifierRule rule, String[] names, String delimiter) {
        return joinNames(_config, rule, names, delimiter);
    }

    @Override
    public String joinNames(String rule, String[] names, String delimiter) {
        return joinNames(_config, getNamingRule(rule), names, delimiter);
    }

    /**
     * Join names using a single naming rule and specified delimiter
     * @param rule
     * @param names
     */
    public String joinNames(IdentifierConfiguration config, IdentifierRule rule, String[] names, String delimiter) {

        if (names == null || names.length == 0) {
            return null;
        }
        StringBuilder combinedName = new StringBuilder();
        for (int i = 0; i < names.length; i++) {
            if (names[i] != null) {
                combinedName.append(delimit(config, rule, names[i], false));
                if (i < (names.length -1)) {
                    combinedName.append(delimiter);
                }
            }
        }
        return combinedName.toString();
    }

    public String[] splitName(IdentifierConfiguration config, IdentifierRule nrule, String name) {
        return splitName(nrule, name, config.getIdentifierDelimiter());
    }

    @Override
    public String[] splitName(IdentifierRule nrule, String name) {
        return splitName(nrule, name, _config.getIdentifierDelimiter());
    }


    /**
     * Splits names using single naming rule and appropriate separators
     * @param name  the multi-value name
     * @return individual components of the name
     *         ex. schema.table --> { schema, table }
     */
    @Override
    public String[] splitName(IdentifierRule nrule, String name, String nameDelim) {
        if (!canSplit(nrule, name, nameDelim) || StringUtil.isEmpty(name)) {
            return new String[] {name};
        }
        // "schema"."table"
        // "sch.ma"."table"
        // "sch""ma".table

        // Split names by object delimiter not between name delimiters
        ArrayList<String> names = new ArrayList<>(2);
        String pname = name;

        // for each name
        int ndLen = nameDelim.length();
        while (!StringUtil.isEmpty(name)) {
            pname = splitNameCharDelimiters(name, nameDelim);
            names.add(pname);
            if ((pname.length() + ndLen) >= name.length()) {
                break;
            }
            name = name.substring(pname.length() + ndLen);
        }
        return names.toArray(new String[names.size()]);
    }

    /**
     * Gets the first part of a name when single character delimiters are
     * in use.
     * @param pname
     */
    private String splitNameCharDelimiters(String name, String nameDelim) {
        StringBuilder sname = new StringBuilder("");
        char ld = _config.getLeadingDelimiter().charAt(0);
        char td = _config.getTrailingDelimiter().charAt(0);
        char nd = nameDelim.charAt(0);
        int dlvl = 0;
        boolean wasLd = false;
        for (int i = 0; i < name.length(); i++) {
            char c = name.charAt(i);
            if (c == ld) {
                // Handle case where delimiters are the same
                if (td == ld && wasLd) {
                    dlvl--;
                    wasLd = false;
                } else {
                    wasLd = true;
                    dlvl++;
                }
            } else if (c == td) {
                dlvl--;
            } else if (c == nd) {
                if (dlvl == 0  && sname.length() > 0) {
                    return sname.toString();
                }
            }
            sname.append(c);
        }
        return sname.toString();
    }

    /**
     * Returns whether a name is double quoted
     */
    public static boolean isDoubleQuoted(String name) {
        if (name == null || name.length() < 3) {
            return false;
        }
        return name.startsWith(DOUBLE_QUOTE) &&
               name.endsWith(DOUBLE_QUOTE);
    }

    public String delimit(IdentifierConfiguration config, IdentifierRule rule, String name) {
        return delimit(config, rule, name, false);
    }


    @Override
    public String delimit(IdentifierRule rule, String name) {
        return delimit(_config, rule, name, false);
    }

    @Override
    public String delimit(IdentifierRule rule, String name, boolean force) {
        return delimit(_config, rule, name, force);
    }

    public String delimit(IdentifierConfiguration config, IdentifierRule rule, String name, boolean force) {
        if (!rule.getCanDelimit() || StringUtil.isEmpty(name)) {
            return name;
        }

        if ((force && !isDelimited(config, rule, name)) || requiresDelimiters(config, rule, name)) {
            return config.getLeadingDelimiter() + name + config.getTrailingDelimiter();
        }
        return name;
    }

    @Override
    public boolean isDelimited(IdentifierRule rule, String name) {
        return isDelimited(_config, rule, name);
    }

    public boolean isDelimited(IdentifierConfiguration config, IdentifierRule rule, String name) {
         if (name == null || name.length() < 3) {
            return false;
        }
        return name.startsWith(config.getLeadingDelimiter()) &&
            name.endsWith(config.getTrailingDelimiter());
    }

    @Override
    public String removeDelimiters(IdentifierConfiguration config, String rule,
        String name) {
        return removeDelimiters(_config, getNamingRule(rule), name, _config.getLeadingDelimiter(),
            _config.getTrailingDelimiter());
    }

    @Override
    public String removeDelimiters(IdentifierRule rule, String name) {
        return removeDelimiters(_config, rule, name, _config.getLeadingDelimiter(),
            _config.getTrailingDelimiter());
    }

    public String removeDelimiters(IdentifierConfiguration config, IdentifierRule rule, String name) {
        return removeDelimiters(config, rule, name, _config.getLeadingDelimiter(),
            _config.getTrailingDelimiter());
    }

    @Override
    public boolean requiresDelimiters(IdentifierRule rule, String name) {
        return requiresDelimiters(_config, rule, name);
    }

    public boolean requiresDelimiters(IdentifierConfiguration config, IdentifierRule rule, String name) {
        if (rule == null) {
            throw new IllegalArgumentException(_loc.get("no-rules-provided").getMessage());
        }
        if (rule.getCanDelimit() && !isDelimited(config, rule, name) && rule.requiresDelimiters(name)) {
            return true;
        }
        return false;
    }

    /**
     * Returns whether a name is considered a reserved word.
     */
    @Override
    public boolean isReservedWord(IdentifierRule rule, String name) {
        if (rule == null) {
            throw new IllegalArgumentException("Naming rule is null!");
        }
        if (rule.getReservedWords() == null) {
            return false;
        }
        if (!isDelimited(rule, name)) {
            name = name.toUpperCase(Locale.ENGLISH);
        }
        return rule.getReservedWords().contains(name);
    }

    @Override
    public boolean isReservedWord(String rule, String name) {
        return isReservedWord(_config.getIdentifierRule(rule), name);
    }


    protected String removeDelimiters(IdentifierConfiguration config, IdentifierRule rule, String name, String leading,
        String trailing) {
        if (name == null) {
            return null;
        }
        if (isDelimited(config, rule, name)) {
            String id = name.substring(leading.length(),
                (name.length() - trailing.length()));
            return id;
        }
        return name;
    }

    @Override
    public String combineNames(String rule, String[] rules, String[] names) {
        return combineNames(getNamingRule(rule), getNamingRules(rules), names);
    }

    @Override
    public String truncateName(String rule, String name, int length) {
        return truncateName(getNamingRule(rule), name, length);
    }

    @Override
    public String truncateName(IdentifierRule namingRule, String name, int length) {
        String tName = name;
        boolean delimited = isDelimited(namingRule, name);
        if (delimited) {
            tName = removeDelimiters(namingRule, name);
        }
        if (tName.length() <= length) {
            return name;
        }
        tName = tName.substring(0, tName.length() - length);
        if (delimited) {
            tName = delimit(namingRule, tName);
        }
        return tName;
    }

    @Override
    public String delimit(String rule, String name) {
        return delimit(getNamingRule(rule), name);
    }

    @Override
    public String delimit(String rule, String name, boolean force) {
        return delimit(getNamingRule(rule), name, force);
    }

    @Override
    public boolean isDelimited(String rule, String name) {
        return isDelimited(getNamingRule(rule), name);
    }

    @Override
    public String removeDelimiters(String rule, String name) {
        return removeDelimiters(getNamingRule(rule), name);
    }

    @Override
    public boolean requiresDelimiters(String rule, String name) {
        return requiresDelimiters(getNamingRule(rule), name);
    }

    public String[] splitName(IdentifierConfiguration config, String rule, String name) {
        return splitName(config, getNamingRule(rule), name);
    }

    @Override
    public String[] splitName(String rule, String name) {
        return splitName(_config, getNamingRule(rule), name);
    }

    @Override
    public String joinNames(String[] rules, String[] names) {
        return joinNames(getNamingRules(rules), names);
    }

    private IdentifierRule getNamingRule(String rule) {
        return _config.getIdentifierRule(rule);
    }

    @Override
    public String appendNames(String rule, String name1, String name2) {
        return appendNames(getNamingRule(rule), name1, name2);
    }

    @Override
    public String removeHungarianNotation(IdentifierRule rule, String name) {
        boolean delimited = isDelimited(rule, name);
        if (delimited) {
            name = removeDelimiters(rule, name);
        }
        char[] chname = name.toCharArray();
        int newStart = 0;

        for (int i = 0; i < chname.length; i++) {
            if (Character.isUpperCase(chname[i]))
            {
                newStart = i;
                break;
            }
        }

        name = name.substring(newStart);
        if (delimited) {
            name = delimit(rule, name);
        }
        return name;
    }

    @Override
    public String removeHungarianNotation(String rule, String name) {
        return removeHungarianNotation(getNamingRule(rule), name);
    }

    @Override
    public String[] splitName(String nrule, String name, String nameDelim) {
        return splitName(getNamingRule(nrule), name, nameDelim);
    }

    @Override
    public String convert(IdentifierConfiguration config, String rule, String name) {
        // Already using same delimiter, no need to convert
        if (!needsConversion(config)) {
            return name;
        }
        // Otherwise, remove delimiters and add appropriate delimiters
        IdentifierRule orule = getIdentifierConfiguration().getIdentifierRule(rule);
        IdentifierRule nrule = config.getIdentifierRule(rule);
        boolean delimit = isDelimited(config, orule, name);
        if (delimit) {
            name = removeDelimiters(config, orule, name, config.getLeadingDelimiter(),
                config.getTrailingDelimiter());
            return delimit(getIdentifierConfiguration(), nrule, name, delimit);
        }
        return name;
    }

    @Override
    public String convertFull(IdentifierConfiguration config, String rule, String fullName) {
        if (!needsConversion(config)) {
            return fullName;
        }
        // Split
        String[] names = splitName(config, rule, fullName);
        // Convert
        for (int i = 0; i < names.length; i++) {
            names[i] = convert(config, rule, names[i]);
        }
        // If a single part name, return it.
        if (names.length == 1) {
            return names[0];
        }
        // Join if multiple names
        return joinNames(getIdentifierConfiguration(), config.getIdentifierRule(rule), names,
            getIdentifierConfiguration().getIdentifierDelimiter());
    }

    public String combineFull(IdentifierConfiguration config, String rule, String fullName) {
        if (!needsConversion(config)) {
            return fullName;
        }
        // Split
        String[] names = splitName(config, rule, fullName);
        // Convert
        for (int i = 0; i < names.length; i++) {
            names[i] = convert(config, rule, names[i]);
        }
        // Join
        return joinNames(config, config.getIdentifierRule(rule), names, config.getIdentifierDelimiter());
    }


    protected boolean needsConversion(IdentifierConfiguration config) {
    	return (config != getIdentifierConfiguration())
           && !(config.getConversionKey().equals(getIdentifierConfiguration().getConversionKey()));
    }

    private IdentifierRule[] getNamingRules(String[] rules) {
        IdentifierRule[] nrules = new IdentifierRule[rules.length];
        for (int i = 0; i < rules.length; i++) {
            nrules[i] = _config.getIdentifierRule(rules[i]);
        }
        return nrules;
    }

    @Override
    public void endConfiguration() {
    }

    @Override
    public void setConfiguration(Configuration conf) {
    }

    @Override
    public void startConfiguration() {
    }

    @Override
    public boolean canSplit(String rule, String name) {
        return canSplit(getNamingRule(rule), name, _config.getIdentifierDelimiter());
    }

    @Override
    public boolean canSplit(IdentifierRule rule, String name) {
        return canSplit(rule, name, _config.getIdentifierDelimiter());
    }

    @Override
    public boolean canSplit(String rule, String name, String delim) {
        return canSplit(getNamingRule(rule), name);
    }

    @Override
    public boolean canSplit(IdentifierRule rule, String name, String delim) {
        if (name == null || name.length() == 0) {
            return false;
        }
        return name.contains(delim);
    }

    @Override
    public String combineNames(IdentifierRule rule, String[] names) {
        return combineNames(_config, rule, names);
    }

    @Override
    public String combineNames(IdentifierRule rule, String name1, String name2) {
        return combineNames(_config, rule, name1, name2);
    }
}
