/*
 * 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.cocoon.i18n;

import org.apache.avalon.framework.parameters.Parameters;

import org.apache.cocoon.environment.Cookie;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Session;
import org.apache.cocoon.environment.Response;
import org.apache.cocoon.util.Deprecation;

import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;

/**
 * A utility class for i18n formatting and parsing routing.
 *
 * @version $Id$
 */
public class I18nUtils {

    /**
     * Locale string delimiter
     */
    private static final String LOCALE_DELIMITER = "_-@.";

    /**
     * Did we already encountered an old namespace? This is static to ensure
     * that the associated message will be logged only once.
     */
    private static boolean deprecationFound = false;

    /**
     * The namespace for i18n is "http://apache.org/cocoon/i18n/2.1".
     */
    public static final String NAMESPACE_URI =
            "http://apache.org/cocoon/i18n/2.1";

    /**
     * The old namespace for i18n is "http://apache.org/cocoon/i18n/2.0".
     */
    public static final String OLD_NAMESPACE_URI =
            "http://apache.org/cocoon/i18n/2.0";


    private I18nUtils() {
        // Disable instantiation
    }

    /**
     * Parses given locale string to Locale object. If the string is null
     * or empty then the given locale is returned.
     *
     * @param localeString - a string containing locale in
     *        <code>language_country_variant</code> format.
     * @param defaultLocale - returned if localeString is <code>null</code>
     *        or <code>""</code>
     */
    public static Locale parseLocale(String localeString, Locale defaultLocale) {
        if (localeString != null && localeString.length() > 0) {
            StringTokenizer st = new StringTokenizer(localeString, LOCALE_DELIMITER);
            String l = st.hasMoreElements() ? st.nextToken() : defaultLocale.getLanguage();
            String c = st.hasMoreElements() ? st.nextToken() : "";
            String v = st.hasMoreElements() ? st.nextToken() : "";
            return new Locale(l, c, v);
        }
        return defaultLocale;
    }

    /**
     * Parses given locale string to Locale object. If the string is null
     * then the VM default locale is returned.
     *
     * @param localeString a string containing locale in
     * <code>language_country_variant</code> format.
     *
     * @see #parseLocale(String, Locale)
     * @see java.util.Locale#getDefault()
     */
    public static Locale parseLocale(String localeString) {
        return parseLocale(localeString, Locale.getDefault());
    }


    /**
     * Callback interface for
     * {@link I18nUtils#findLocale(Map, String, Parameters, Locale, boolean, boolean, boolean, I18nUtils.LocaleValidator)}
     * @since 2.1.6
     */
    public interface LocaleValidator {

        /**
         * @param name of the locale (for debugging)
         * @param locale to test
         * @return true if locale satisfies validator's criteria
         */
        public boolean test(String name, Locale locale);
    }

    /**
     * Find a suitable locale from an objectModel.
     * @since 2.1.6
     * @return locale found, or null if none found.
     */
    public static Locale findLocale(Map objectModel,
                                    String attribute,
                                    Parameters parameters,
                                    Locale defaultLocale,
                                    boolean useLocale,
                                    boolean useLocales,
                                    boolean useBlankLocale,
                                    LocaleValidator test) {
        String localeStr;
        Locale locale;

        Request request = ObjectModelHelper.getRequest(objectModel);

        // 1. Request parameter 'locale'
        localeStr = request.getParameter(attribute);
        if (localeStr != null) {
            locale = parseLocale(localeStr);
            if (test == null || test.test("request", locale)) {
                return locale;
            }
        }

        // 2. Session attribute 'locale'
        Session session = request.getSession(false);
        if (session != null &&
                ((localeStr = (String) session.getAttribute(attribute)) != null)) {
            locale = parseLocale(localeStr);
            if (test == null || test.test("session", locale)) {
                return locale;
            }
        }

        // 3. First matching cookie parameter 'locale' within each cookie sent
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (int i = 0; i < cookies.length; i++) {
                Cookie cookie = cookies[i];
                if (cookie.getName().equals(attribute)) {
                    localeStr = cookie.getValue();
                    locale = parseLocale(localeStr);
                    if (test == null || test.test("cookie", locale)) {
                        return locale;
                    }
                    break;
                }
            }
        }

        // 4. Sitemap parameter "locale"
        if (parameters != null) {
            localeStr = parameters.getParameter("locale", null);
            if (localeStr != null) {
                locale = parseLocale(localeStr);
                if (test == null || test.test("sitemap", locale)) {
                    return locale;
                }
            }
        }

        // 5. Locale setting of the requesting browser or server default
        if (useLocale && !useLocales) {
            locale = request.getLocale();
            if (test == null || test.test("request", locale)) {
                return locale;
            }
        }
        if (useLocales) {
            Enumeration locales = request.getLocales();
            while (locales.hasMoreElements()) {
                locale = (Locale)locales.nextElement();
                if (test == null || test.test("request", locale)) {
                    return locale;
                }
            }
        }

        // 6. Default
        if (defaultLocale != null) {
            locale = defaultLocale;
            if (test == null || test.test("default", locale)) {
                return locale;
            }
        }

        // 7. Blank
        if (useBlankLocale) {
            locale = new Locale("", "");
            if (test == null || test.test("blank", locale)) {
                return locale;
            }
        }

        // 8. Fail
        return null;
    }

    /**
     * Find a suitable locale from an objectModel.
     * @since 2.1.6
     * @return locale found, or server default (never null).
     */
    public static Locale findLocale(Map objectModel,
                                    String attribute,
                                    Parameters parameters,
                                    Locale defaultLocale,
                                    boolean useLocale) {
        return findLocale(objectModel, attribute, parameters, defaultLocale, useLocale, false, false, null);
    }

    /**
     * Store locale in request, session, or cookie.
     * @since 2.1.6
     */
    public static void storeLocale(Map objectModel,
                                   String attribute,
                                   String locale,
                                   boolean storeInRequest,
                                   boolean storeInSession,
                                   boolean storeInCookie,
                                   boolean createSession) {
        // store in a request if so configured
        if (storeInRequest) {
            Request request = ObjectModelHelper.getRequest(objectModel);
            request.setAttribute(attribute, locale);
        }

        // store in session if so configured
        if (storeInSession) {
            Request request = ObjectModelHelper.getRequest(objectModel);
            Session session = request.getSession(createSession);
            if (session != null) {
                session.setAttribute(attribute, locale);
            }
        }

        // store in a cookie if so configured
        if (storeInCookie) {
            Response response = ObjectModelHelper.getResponse(objectModel);
            response.addCookie(response.createCookie(attribute, locale));
        }
    }

    public static boolean matchesI18nNamespace(String uri) {
        if (NAMESPACE_URI.equals(uri)) {
            return true;
        } else if (OLD_NAMESPACE_URI.equals(uri)) {
            if (!deprecationFound) {
                deprecationFound = true;
                Deprecation.logger.warn("The namespace <" + OLD_NAMESPACE_URI +
                                        "> is deprecated, use: <" + NAMESPACE_URI + ">");
            }
            return true;
        }
        return false;
    }

}
