/*
    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.wiki.ui;

import org.apache.log4j.Logger;
import org.apache.wiki.WikiContext;
import org.apache.wiki.api.core.Context;
import org.apache.wiki.i18n.InternationalizationManager;
import org.apache.wiki.modules.ModuleManager;
import org.apache.wiki.preferences.Preferences;
import org.apache.wiki.util.ClassUtil;

import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.jstl.fmt.LocaleSupport;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.TimeZone;
import java.util.Vector;


/**
 *  This class takes care of managing JSPWiki templates.  This class also provides the ResourceRequest mechanism.
 *
 *  @since 2.1.62
 */
public interface TemplateManager extends ModuleManager {

    String SKIN_DIRECTORY = "skins";

    /** Requests a JavaScript function to be called during window.onload. Value is {@value}. */
    String RESOURCE_JSFUNCTION = "jsfunction";

    /** Requests a JavaScript associative array with all localized strings. */
    String RESOURCE_JSLOCALIZEDSTRINGS = "jslocalizedstrings";

    /** Requests a stylesheet to be inserted. Value is {@value}. */
    String RESOURCE_STYLESHEET = "stylesheet";

    /** Requests a script to be loaded. Value is {@value}. */
    String RESOURCE_SCRIPT = "script";

    /** Requests inlined CSS. Value is {@value}. */
    String RESOURCE_INLINECSS = "inlinecss";

    /** The default directory for the properties. Value is {@value}. */
    String DIRECTORY = "templates";

    /** The name of the default template. Value is {@value}. */
    String DEFAULT_TEMPLATE = "default";

    /** Name of the file that contains the properties. */
    String PROPERTYFILE = "template.properties";

    /** Location of I18N Resource bundles, and path prefix and suffixes */
    String I18NRESOURCE_PREFIX = "templates/default_";

    String I18NRESOURCE_SUFFIX = ".properties";

    /** The default (en) RESOURCE name and id. */
    String I18NRESOURCE_EN = "templates/default.properties";
    String I18NRESOURCE_EN_ID = "en";

    /** I18N string to mark the default locale */
    String I18NDEFAULT_LOCALE = "prefs.user.language.default";

    /** I18N string to mark the server timezone */
    String I18NSERVER_TIMEZONE = "prefs.user.timezone.server";

    /** Prefix of the default timeformat properties. */
    String TIMEFORMATPROPERTIES = "jspwiki.defaultprefs.timeformat.";

    /** The name under which the resource includes map is stored in the  WikiContext. */
    String RESOURCE_INCLUDES = "jspwiki.resourceincludes";

    /** Requests a HTTP header. Value is {@value}. */
    String RESOURCE_HTTPHEADER = "httpheader";

    /**
     *  Check the existence of a template.
     */
    boolean templateExists( String templateName );

    /**
     *  An utility method for finding a JSP page.  It searches only under either current context or by the absolute name.
     *
     *  @param pageContext the JSP PageContext
     *  @param name The name of the JSP page to look for (e.g "Wiki.jsp")
     *  @return The context path to the resource
     */
    String findJSP( PageContext pageContext, String name );

    /**
     *  Attempts to locate a resource under the given template.  If that template does not exist, or the page does not exist under that
     *  template, will attempt to locate a similarly named file under the default template.
     *  <p>
     *  Even though the name suggests only JSP files can be located, but in fact this method can find also other resources than JSP files.
     *
     *  @param pageContext The JSP PageContext
     *  @param template From which template we should seek initially?
     *  @param name Which resource are we looking for (e.g. "ViewTemplate.jsp")
     *  @return path to the JSP page; null, if it was not found.
     */
    String findJSP( PageContext pageContext, String template, String name );

    /**
     *  Attempts to locate a resource under the given template.  This matches the functionality findJSP(), but uses the WikiContext as
     *  the argument.  If there is no servlet context (i.e. this is embedded), will just simply return a best-guess.
     *  <p>
     *  This method is typically used to locate any resource, including JSP pages, images, scripts, etc.
     *
     *  @since 2.6
     *  @param ctx the wiki context
     *  @param template the name of the template to use
     *  @param name the name of the resource to fine
     *  @return the path to the resource
     */
    String findResource( Context ctx, String template, String name );

    /**
     *   Lists the skins available under this template.  Returns an empty Set, if there are no extra skins available.  Note that
     *   this method does not check whether there is anything actually in the directories, it just lists them.  This may change
     *   in the future.
     *
     *   @param pageContext the JSP PageContext
     *   @param template The template to search
     *   @return Set of Strings with the skin names.
     *   @since 2.3.26
     */
    Set< String > listSkins( PageContext pageContext, String template );

    /**
     * List all installed i18n language properties by classpath searching for files like :
     *    templates/default_*.properties
     *    templates/default.properties
     *
     * @param pageContext page context
     * @return map of installed Languages
     * @since 2.7.x
     */
    default Map< String, String > listLanguages( final PageContext pageContext ) {
        final Map< String, String > resultMap = new LinkedHashMap<>();
        final String clientLanguage = pageContext.getRequest().getLocale().toString();
        final List< String > entries = ClassUtil.classpathEntriesUnder( DIRECTORY );
        for( String name : entries ) {
            if ( name.equals( I18NRESOURCE_EN ) || (name.startsWith( I18NRESOURCE_PREFIX ) && name.endsWith( I18NRESOURCE_SUFFIX ) ) ) {
                if( name.equals( I18NRESOURCE_EN ) ) {
                    name = I18NRESOURCE_EN_ID;
                } else {
                    name = name.substring( I18NRESOURCE_PREFIX.length(), name.lastIndexOf( I18NRESOURCE_SUFFIX ) );
                }
                final Locale locale = new Locale( name.substring( 0, 2 ), !name.contains( "_" ) ? "" : name.substring( 3, 5 ) );
                String defaultLanguage = "";
                if( clientLanguage.startsWith( name ) ) {
                    defaultLanguage = LocaleSupport.getLocalizedMessage( pageContext, I18NDEFAULT_LOCALE );
                }
                resultMap.put( name, locale.getDisplayName( locale ) + " " + defaultLanguage );
            }
        }

        return resultMap;
    }


    /**
     * List all available timeformats, read from the jspwiki.properties
     *
     * @param pageContext page context
     * @return map of TimeFormats
     * @since 2.7.x
     */
    Map< String, String > listTimeFormats( final PageContext pageContext );

    /**
     * List all timezones, with special marker for server timezone
     *
     * @param pageContext page context
     * @return map of TimeZones
     * @since 2.7.x
     */
    default Map< String, String > listTimeZones( final PageContext pageContext ) {
        final Map< String, String > resultMap = new LinkedHashMap<>();
        final String[][] tzs = {
                          { "GMT-12", "Enitwetok, Kwajalien" },
                          { "GMT-11", "Nome, Midway Island, Samoa" },
                          { "GMT-10", "Hawaii" },
                          { "GMT-9", "Alaska" },
                          { "GMT-8", "Pacific Time" },
                          { "GMT-7", "Mountain Time" },
                          { "GMT-6", "Central Time, Mexico City" },
                          { "GMT-5", "Eastern Time, Bogota, Lima, Quito" },
                          { "GMT-4", "Atlantic Time, Caracas, La Paz" },
                          { "GMT-3:30", "Newfoundland" },
                          { "GMT-3", "Brazil, Buenos Aires, Georgetown, Falkland Is." },
                          { "GMT-2", "Mid-Atlantic, Ascention Is., St Helena" },
                          { "GMT-1", "Azores, Cape Verde Islands" },
                          { "GMT", "Casablanca, Dublin, Edinburgh, London, Lisbon, Monrovia" },
                          { "GMT+1", "Berlin, Brussels, Copenhagen, Madrid, Paris, Rome" },
                          { "GMT+2", "Helsinki, Athens, Kaliningrad, South Africa, Warsaw" },
                          { "GMT+3", "Baghdad, Riyadh, Moscow, Nairobi" },
                          { "GMT+3:30", "Tehran" },
                          { "GMT+4", "Adu Dhabi, Baku, Muscat, Tbilisi" },
                          { "GMT+4:30", "Kabul" },
                          { "GMT+5", "Islamabad, Karachi, Tashkent" },
                          { "GMT+5:30", "Bombay, Calcutta, Madras, New Delhi" },
                          { "GMT+6", "Almaty, Colomba, Dhakra" },
                          { "GMT+7", "Bangkok, Hanoi, Jakarta" },
                          { "GMT+8", "Beijing, Hong Kong, Perth, Singapore, Taipei" },
                          { "GMT+9", "Osaka, Sapporo, Seoul, Tokyo, Yakutsk" },
                          { "GMT+9:30", "Adelaide, Darwin" },
                          { "GMT+10", "Melbourne, Papua New Guinea, Sydney, Vladivostok" },
                          { "GMT+11", "Magadan, New Caledonia, Solomon Islands" },
                          { "GMT+12", "Auckland, Wellington, Fiji, Marshall Island" } };

        final TimeZone servertz = TimeZone.getDefault();
        for( final String[] strings : tzs ) {
            String tzID = strings[ 0 ];
            final TimeZone tz = TimeZone.getTimeZone( tzID );
            String serverTimeZone = "";
            if( servertz.getRawOffset() == tz.getRawOffset() ) {
                serverTimeZone = LocaleSupport.getLocalizedMessage( pageContext, I18NSERVER_TIMEZONE );
                tzID = servertz.getID();
            }

            resultMap.put( tzID, "(" + strings[ 0 ] + ") " + strings[ 1 ] + " " + serverTimeZone );
        }

        return resultMap;
    }

    /**
     *  Returns the include resources marker for a given type.  This is in a
     *  HTML or Javascript comment format.
     *
     *  @param context the wiki context
     *  @param type the marker
     *  @return the generated marker comment
     */
    static String getMarker( final WikiContext context, final String type ) {
        if( type.equals( RESOURCE_JSLOCALIZEDSTRINGS ) ) {
            return getJSLocalizedStrings( context );
        } else if( type.equals( RESOURCE_JSFUNCTION ) ) {
            return "/* INCLUDERESOURCES ("+type+") */";
        }
        return "<!-- INCLUDERESOURCES ("+type+") -->";
    }

    /**
     *  Extract all i18n strings in the javascript domain. (javascript.*) Returns a javascript snippet which defines the LocalizedStings array.
     *
     *  @param context the {@link WikiContext}
     *  @return Javascript snippet which defines the LocalizedStrings array
     *  @since 2.5.108
     */
    static String getJSLocalizedStrings( final WikiContext context ) {
        final StringBuilder sb = new StringBuilder();
        sb.append( "var LocalizedStrings = {\n");
        final ResourceBundle rb = Preferences.getBundle( context, InternationalizationManager.DEF_TEMPLATE );
        boolean first = true;

        for( final Enumeration< String > en = rb.getKeys(); en.hasMoreElements(); ) {
            final String key = en.nextElement();
            if( key.startsWith("javascript") ) {
                if( first ) {
                    first = false;
                } else {
                    sb.append( ",\n" );
                }
                sb.append( "\"" ).append( key ).append( "\":\"" ).append( rb.getString( key ) ).append( "\"" );
            }
        }
        sb.append("\n};\n");

        return( sb.toString() );
    }

    /**
     *  Adds a resource request to the current request context. The content will be added at the resource-type marker
     *  (see IncludeResourcesTag) in WikiJSPFilter.
     *  <p>
     *  The resources can be of different types.  For RESOURCE_SCRIPT and RESOURCE_STYLESHEET this is an URI path to the resource
     *  (a script file or an external stylesheet) that needs to be included.  For RESOURCE_INLINECSS the resource should be something
     *  that can be added between &lt;style>&lt;/style> in the header file (commonheader.jsp).  For RESOURCE_JSFUNCTION it is the name
     *  of the Javascript function that should be run at page load.
     *  <p>
     *  The IncludeResourceTag inserts code in the template files, which is then filled by the WikiFilter after the request has been
     *  rendered but not yet sent to the recipient.
     *  <p>
     *  Note that ALL resource requests get rendered, so this method does not check if the request already exists in the resources.
     *  Therefore, if you have a plugin which makes a new resource request every time, you'll end up with multiple resource requests
     *  rendered.  It's thus a good idea to make this request only once during the page life cycle.
     *
     *  @param ctx The current wiki context
     *  @param type What kind of a request should be added?
     *  @param resource The resource to add.
     */
    @SuppressWarnings("unchecked")
    static void addResourceRequest( final WikiContext ctx, final String type, final String resource ) {
        HashMap< String, Vector< String > > resourcemap = ( HashMap< String, Vector< String > > ) ctx.getVariable( RESOURCE_INCLUDES );
        if( resourcemap == null ) {
            resourcemap = new HashMap<>();
        }

        Vector< String > resources = resourcemap.get( type );
        if( resources == null ) {
            resources = new Vector<>();
        }

        String resourceString = null;
        switch( type ) {
        case RESOURCE_SCRIPT:
            resourceString = "<script type='text/javascript' src='" + resource + "'></script>";
            break;
        case RESOURCE_STYLESHEET:
            resourceString = "<link rel='stylesheet' type='text/css' href='" + resource + "' />";
            break;
        case RESOURCE_INLINECSS:
            resourceString = "<style type='text/css'>\n" + resource + "\n</style>\n";
            break;
        case RESOURCE_JSFUNCTION:
        case RESOURCE_HTTPHEADER:
            resourceString = resource;
            break;
        }

        if( resourceString != null ) {
            resources.add( resourceString );
        }

        Logger.getLogger( TemplateManager.class ).debug( "Request to add a resource: " + resourceString );

        resourcemap.put( type, resources );
        ctx.setVariable( RESOURCE_INCLUDES, resourcemap );
    }

    /**
     *  Returns resource requests for a particular type.  If there are no resources, returns an empty array.
     *
     *  @param ctx WikiContext
     *  @param type The resource request type
     *  @return a String array for the resource requests
     */
    @SuppressWarnings("unchecked")
    static String[] getResourceRequests( final WikiContext ctx, final String type ) {
        final HashMap< String, Vector< String > > hm = ( HashMap< String, Vector< String > > ) ctx.getVariable( RESOURCE_INCLUDES );
        if( hm == null ) {
            return new String[0];
        }

        final Vector<String> resources = hm.get( type );
        if( resources == null ){
            return new String[0];
        }

        final String[] res = new String[resources.size()];
        return resources.toArray( res );
    }

    /**
     *  Returns all those types that have been requested so far.
     *
     * @param ctx the wiki context
     * @return the array of types requested
     */
    @SuppressWarnings("unchecked")
    static String[] getResourceTypes( final WikiContext ctx ) {
        String[] res = new String[0];
        if( ctx != null ) {
            final HashMap< String, String > hm = ( HashMap< String, String > ) ctx.getVariable( RESOURCE_INCLUDES );
            if( hm != null ) {
                final Set< String > keys = hm.keySet();
                res = keys.toArray( res );
            }
        }

        return res;
    }

}
