/*
 * 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.felix.webconsole.internal.configuration;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.felix.utils.json.JSONWriter;
import org.apache.felix.webconsole.SimpleWebConsolePlugin;
import org.apache.felix.webconsole.WebConsoleConstants;
import org.apache.felix.webconsole.WebConsoleUtil;
import org.apache.felix.webconsole.internal.OsgiManagerPlugin;
import org.apache.felix.webconsole.internal.Util;
import org.apache.felix.webconsole.internal.misc.ServletSupport;
import org.apache.felix.webconsole.spi.ConfigurationHandler;
import org.apache.felix.webconsole.spi.ValidationException;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.cm.Configuration;
import org.osgi.util.tracker.ServiceTracker;


/**
 * The <code>ConfigManager</code> class is the Web Console plugin to
 * manage configurations.
 */
public class ConfigManager extends SimpleWebConsolePlugin implements OsgiManagerPlugin, ServletSupport
{

    private static final long serialVersionUID = 5021174538498622428L;

    private static final String LABEL = "configMgr"; // was name //$NON-NLS-1$
    private static final String TITLE = "%configMgr.pluginTitle"; //$NON-NLS-1$
    private static final String CSS[] = { "/res/ui/config.css" }; //$NON-NLS-1$

    static final String PID_FILTER = "pidFilter"; //$NON-NLS-1$
    static final String PID = "pid"; //$NON-NLS-1$
    static final String FACTORY_PID = "factoryPid"; //$NON-NLS-1$
    static final String REFERER = "referer"; //$NON-NLS-1$
    static final String FACTORY_CREATE = "factoryCreate"; //$NON-NLS-1$

    static final String ACTION_CREATE = "create"; //$NON-NLS-1$
    static final String ACTION_DELETE = "delete"; //$NON-NLS-1$
    static final String ACTION_APPLY = "apply"; //$NON-NLS-1$
    static final String ACTION_UPDATE = "update"; //$NON-NLS-1$
    static final String ACTION_UNBIND = "unbind"; //$NON-NLS-1$
    static final String PROPERTY_LIST = "propertylist"; //$NON-NLS-1$
    static final String LOCATION = "$location"; //$NON-NLS-1$

    static final String CONFIGURATION_ADMIN_NAME = "org.osgi.service.cm.ConfigurationAdmin"; //$NON-NLS-1$
    static final String META_TYPE_NAME = "org.osgi.service.metatype.MetaTypeService"; //$NON-NLS-1$

    public static final String UNBOUND_LOCATION = "??unbound:bundle/location"; //$NON-NLS-1$

    // templates
    private final String TEMPLATE;

    // service tracker for SPI
    private ServiceTracker<ConfigurationHandler, ConfigurationHandler> spiTracker;

    /** Default constructor */
    public ConfigManager() {
        super(LABEL, TITLE, CATEGORY_OSGI, CSS);

        // load templates
        TEMPLATE = readTemplateFile( "/templates/config.html" ); //$NON-NLS-1$
    }

    @Override
    public void activate(final BundleContext bundleContext) {
        super.activate(bundleContext);
        this.spiTracker = new ServiceTracker<>(bundleContext, ConfigurationHandler.class.getName(), null);
        this.spiTracker.open(true);
    }


    @Override
    public void deactivate() {
        if ( this.spiTracker != null ) {
            this.spiTracker.close();
            this.spiTracker = null;
        }
        super.deactivate();
    }

    /**
     * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws IOException {
        // service unavailable if config admin is not available
        final ConfigAdminSupport cas = getConfigurationAdminSupport();
        if ( cas == null ) {
            response.sendError(503);
            return;
        }

        // needed multiple times below
        String pid = request.getParameter( ConfigManager.PID );
        if ( pid == null ) {
            String info = request.getPathInfo();
            pid = WebConsoleUtil.urlDecode( info.substring( info.lastIndexOf( '/' ) + 1 ) );
        }
        // ignore this request if the PID is invalid / not provided
        if ( pid == null || pid.length() == 0 || !ConfigurationUtil.isAllowedPid(pid)) {
            response.sendError(400);
            return;
        }

        // the filter to select part of the configurations
        final String pidFilter = request.getParameter( PID_FILTER );
        if ( pidFilter != null && !ConfigurationUtil.isAllowedPid(pidFilter) ) {
            response.sendError(400);
            return;
        }

        if ( request.getParameter( ACTION_APPLY ) != null ) {
            if ( request.getParameter( ConfigManager.ACTION_DELETE ) != null ) { //$NON-NLS-1$
                try {
                    cas.deleteConfiguration( pid );
                    Util.sendJsonOk(response);
                } catch ( final ValidationException ve) {
                    response.sendError(400, ve.getMessage());
                }
            }
            else
            {
                final String propertyList = request.getParameter( ConfigManager.PROPERTY_LIST ); //$NON-NLS-1$
                if ( propertyList == null ) {
                    response.sendError(400);
                    return;
                }

                try {
                    String redirect = cas.applyConfiguration( request, pid, propertyList.split(","), ACTION_UPDATE.equals(request.getParameter(ACTION_APPLY)));
                    if (pidFilter != null) {
                        redirect = redirect.concat("?").concat(PID_FILTER).concat("=").concat(pidFilter);
                    }

                    WebConsoleUtil.sendRedirect(request, response, redirect);
                } catch ( final ValidationException ve) {
                    response.sendError(400, ve.getMessage());
                }
            }

            return;
        }

        // the configuration to operate on (to be created or "missing")
        final Configuration config;

        // should actually apply the configuration before redirecting
        if ( request.getParameter( ACTION_CREATE ) != null ) {
            config = ConfigurationUtil.getPlaceholderConfiguration( pid );
            pid = config.getPid();
        } else {
            config = cas.findConfiguration( pid );
        }

        // check for configuration unbinding
        if ( request.getParameter( ACTION_UNBIND ) != null )
        {
            if ( config != null && config.getBundleLocation() != null ) {
                config.setBundleLocation( UNBOUND_LOCATION );

            }
            Util.sendJsonOk(response);
            return;
        }

        // send the result
        response.setContentType( "application/json" ); //$NON-NLS-1$
        response.setCharacterEncoding( "UTF-8" ); //$NON-NLS-1$
        final Locale loc = Util.getLocale( request );
        final String locale = ( loc != null ) ? loc.toString() : null;
        cas.getJsonSupport().printConfigurationJson( response.getWriter(), pid, config, pidFilter, locale );
    }


    /**
     * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    protected void doGet( HttpServletRequest request, HttpServletResponse response )
            throws ServletException, IOException {
        // check for "post" requests from previous versions
        if ( "true".equals(request.getParameter("post")) ) { //$NON-NLS-1$ //$NON-NLS-2$
            this.doPost(request, response);
            return;
        }
        final String info = request.getPathInfo();
        // let's check for a JSON request
        if ( info.endsWith( ".json" ) ) //$NON-NLS-1$
        {
            response.setContentType( "application/json" ); //$NON-NLS-1$
            response.setCharacterEncoding( "UTF-8" ); //$NON-NLS-1$

            // after last slash and without extension
            String pid = info.substring( info.lastIndexOf( '/' ) + 1, info.length() - 5 );
            // check whether the PID is actually a filter for the selection
            // of configurations to display, if the filter correctly converts
            // into an OSGi filter, we use it to select configurations
            // to display
            String pidFilter = request.getParameter( PID_FILTER );
            if ( pidFilter == null )
            {
                pidFilter = pid;
            }
            try
            {
                getBundleContext().createFilter( pidFilter );

                // if the pidFilter was set from the PID, clear the PID
                if ( pid == pidFilter )
                {
                    pid = null;
                }
            }
            catch ( InvalidSyntaxException ise )
            {
                // its OK, if the PID is just a single PID
                pidFilter = null;
            }

            // check both PID and PID filter
            if ( pid != null && !ConfigurationUtil.isAllowedPid(pid) )
            {
                response.sendError(400);
            }
            if ( pidFilter != null && !ConfigurationUtil.isAllowedPid(pidFilter) )
            {
                response.sendError(400);
            }


            final Locale loc = Util.getLocale( request );
            final String locale = ( loc != null ) ? loc.toString() : null;

            final PrintWriter pw = response.getWriter();
            pw.write( "[" ); //$NON-NLS-1$
            final ConfigAdminSupport ca = this.getConfigurationAdminSupport();
            if ( ca != null )
            {
                // create filter
                final StringBuffer sb = new StringBuffer();
                if ( pid != null && pidFilter != null)
                {
                    sb.append("(&"); //$NON-NLS-1$
                }
                if ( pid != null )
                {
                    sb.append('(');
                    sb.append(Constants.SERVICE_PID);
                    sb.append('=');
                    sb.append(pid);
                    sb.append(')');
                }
                if ( pidFilter != null )
                {
                    sb.append(pidFilter);
                }
                if ( pid != null && pidFilter != null)
                {
                    sb.append(')');
                }
                final String filter = sb.toString();
                try
                {
                    // we use listConfigurations to not create configuration
                    // objects persistently without the user providing actual
                    // configuration
                    final Configuration[] configs = ca.listConfigurations( filter );
                    boolean printComma = false;
                    for(int i=0; configs != null && i<configs.length; i++)
                    {
                        final Configuration config = configs[i];
                        if ( config != null )
                        {
                            if ( printComma )
                            {
                                pw.print( ',' );
                            }
                            ca.getJsonSupport().printConfigurationJson( pw, config.getPid(), config, null, locale );
                            printComma = true;
                        }
                    }
                }
                catch ( final InvalidSyntaxException ise )
                {
                    // should print message
                    // however this should not happen as we checked the filter before
                }
                catch ( final IOException ioe )
                {
                    // should print message
                }
            }
            pw.write( "]" ); //$NON-NLS-1$

            // nothing more to do
            return;
        }

        super.doGet( request, response );
    }

    /**
     * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#renderContent(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    protected void renderContent( HttpServletRequest request, HttpServletResponse response ) throws IOException
    {

        // extract the configuration PID from the request path
        String pid = request.getPathInfo().substring(this.getLabel().length() + 1);
        if ( pid.length() == 0 ) {
            pid = null;
        } else {
            pid = pid.substring( pid.lastIndexOf( '/' ) + 1 );
        }
        // check whether the PID is actually a filter for the selection
        // of configurations to display, if the filter correctly converts
        // into an OSGi filter, we use it to select configurations
        // to display
        String pidFilter = request.getParameter( PID_FILTER );
        if ( pidFilter == null )
        {
            pidFilter = pid;
        }
        if ( pidFilter != null )
        {
            try
            {
                getBundleContext().createFilter( pidFilter );

                // if the pidFilter was set from the PID, clear the PID
                if ( pid == pidFilter )
                {
                    pid = null;
                }
            }
            catch ( InvalidSyntaxException ise )
            {
                // its OK, if the PID is just a single PID
                pidFilter = null;
            }
        }

        // check both PID and PID filter
        if ( pid != null && !ConfigurationUtil.isAllowedPid(pid) )
        {
            response.sendError(400);
        }
        if ( pidFilter != null && !ConfigurationUtil.isAllowedPid(pidFilter) )
        {
            response.sendError(400);
        }

        final Locale loc = Util.getLocale( request );
        final String locale = ( loc != null ) ? loc.toString() : null;


        StringWriter json = new StringWriter();
        JSONWriter jw = new JSONWriter(json);
        jw.object();
        final ConfigAdminSupport cas = getConfigurationAdminSupport();
        // check for osgi installer plugin
        @SuppressWarnings("unchecked")
        final Map<String, Object> labelMap = (Map<String, Object>) request.getAttribute(WebConsoleConstants.ATTR_LABEL_MAP);
        jw.key("jsonsupport").value( labelMap.containsKey("osgi-installer-config-printer") ); //$NON-NLS-1$
        final boolean hasMetatype = cas.getMetaTypeSupport() != null;
        jw.key("status").value( cas != null ? Boolean.TRUE : Boolean.FALSE); //$NON-NLS-1$
        jw.key("metatype").value( hasMetatype ? Boolean.TRUE : Boolean.FALSE); //$NON-NLS-1$
        boolean hasConfigs = true;
        if ( cas != null )
        {
            hasConfigs = cas.getJsonSupport().listConfigurations( jw, pidFilter, locale, loc);
            cas.getJsonSupport().listFactoryConfigurations( jw, pidFilter, locale );
        }
        if ( !hasConfigs && !hasMetatype && cas != null ) {
            jw.key("noconfigs").value(true); //$NON-NLS-1$
        } else {
            jw.key("noconfigs").value(false); //$NON-NLS-1$
        }

        jw.endObject();

        // if a configuration is addressed, display it immediately
        if ( request.getParameter( ACTION_CREATE ) != null && pid != null ) {
            pid = ConfigurationUtil.getPlaceholderPid();
        }


        // prepare variables
        final String referer = request.getParameter( REFERER );
        final boolean factoryCreate = "true".equals( request.getParameter(FACTORY_CREATE) ); //$NON-NLS-1$
        final Map<String, Object> vars = ( ( Map<String, Object> ) WebConsoleUtil.getVariableResolver( request ) );
        vars.put( "__data__", json.toString() ); //$NON-NLS-1$
        vars.put( "selectedPid", pid != null ? pid : "" ); //$NON-NLS-1$ //$NON-NLS-2$
        vars.put( "configurationReferer", referer != null ? referer : "" ); //$NON-NLS-1$ //$NON-NLS-2$
        vars.put( "factoryCreate", Boolean.valueOf(factoryCreate) ); //$NON-NLS-1$
        vars.put( "param.apply", ACTION_APPLY ); //$NON-NLS-1$
        vars.put( "param.create", ACTION_CREATE ); //$NON-NLS-1$
        vars.put( "param.unbind", ACTION_UNBIND ); //$NON-NLS-1$
        vars.put( "param.delete", ACTION_DELETE ); //$NON-NLS-1$
        vars.put( "param.propertylist", PROPERTY_LIST ); //$NON-NLS-1$
        vars.put( "param.pidFilter", PID_FILTER ); //$NON-NLS-1$

        response.getWriter().print(TEMPLATE);
    }

    private ConfigAdminSupport getConfigurationAdminSupport() {
        Object configurationAdmin = getService( CONFIGURATION_ADMIN_NAME );
        if ( configurationAdmin != null ) {
            final List<ConfigurationHandler> handlers = new ArrayList<>();
            Object[] services = this.spiTracker.getServices();
            if (services != null) {
                for(final Object o : services) {
                    handlers.add((ConfigurationHandler)o);
                }
            }
            return new ConfigAdminSupport( this, configurationAdmin, handlers );
        }
        return null;
    }

    @Override
    public BundleContext getBundleContext() {
        return super.getBundleContext();
    }
}

