/**
 * 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.cxf.dosgi.dsw.handlers;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.cxf.dosgi.dsw.Constants;
import org.apache.cxf.dosgi.dsw.api.DistributionProvider;
import org.apache.cxf.dosgi.dsw.api.Endpoint;
import org.apache.cxf.dosgi.dsw.api.IntentUnsatisfiedException;
import org.apache.cxf.dosgi.dsw.qos.IntentManager;
import org.apache.cxf.dosgi.dsw.util.OsgiUtils;
import org.apache.cxf.dosgi.dsw.util.StringPlus;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.remoteserviceadmin.EndpointDescription;
import org.osgi.service.remoteserviceadmin.RemoteConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CXFDistributionProvider implements DistributionProvider {

    protected static final String DEFAULT_CONFIGURATION_TYPE = Constants.WS_CONFIG_TYPE;
    private static final Logger LOG = LoggerFactory.getLogger(CXFDistributionProvider.class);

    // protected because of tests
    protected final String[] supportedConfigurationTypes;

    private IntentManager intentManager;
    private PojoConfigurationTypeHandler pojoConfigurationTypeHandler;
    private JaxRSPojoConfigurationTypeHandler jaxRsPojoConfigurationTypeHandler;
    private WsdlConfigurationTypeHandler wsdlConfigurationTypeHandler;
    private Set<String> configTypesSet;

    public CXFDistributionProvider(BundleContext bc, IntentManager intentManager,
                                    HttpServiceManager httpServiceManager) {
        this.intentManager = intentManager;
        this.pojoConfigurationTypeHandler = new PojoConfigurationTypeHandler(bc, intentManager, httpServiceManager);
        this.jaxRsPojoConfigurationTypeHandler = new JaxRSPojoConfigurationTypeHandler(bc,
                                                                                       intentManager,
                                                                                       httpServiceManager);
        this.wsdlConfigurationTypeHandler = new WsdlConfigurationTypeHandler(bc, intentManager, httpServiceManager);
        supportedConfigurationTypes = new String[] {Constants.WS_CONFIG_TYPE,
                                                    Constants.WSDL_CONFIG_TYPE, 
                                                    Constants.RS_CONFIG_TYPE, 
                                                    Constants.WS_CONFIG_TYPE_OLD};
        configTypesSet = new HashSet<>(Arrays.asList(supportedConfigurationTypes));
    }
    
    @Override
    public Endpoint exportService(ServiceReference<?> sref, Map<String, Object> effectiveProperties,
                                  String exportedInterface) {
        List<String> configurationTypes = determineConfigurationTypes(effectiveProperties);
        DistributionProvider handler = getHandler(configurationTypes, effectiveProperties);
        return handler != null ? handler.exportService(sref, effectiveProperties, exportedInterface) : null;
    }

    @Override
    public Object importEndpoint(BundleContext consumerContext, Class<?>[] iClass, EndpointDescription endpoint)
        throws IntentUnsatisfiedException {
        List<String> configurationTypes = determineConfigTypesForImport(endpoint);
        DistributionProvider handler = getHandler(configurationTypes, endpoint.getProperties());
        return handler != null ? handler.importEndpoint(consumerContext, iClass, endpoint) : null;
    }

    DistributionProvider getHandler(List<String> configurationTypes,
                                            Map<String, Object> serviceProperties) {
        intentManager.assertAllIntentsSupported(serviceProperties);
        if (configurationTypes.contains(Constants.WS_CONFIG_TYPE)
            || configurationTypes.contains(Constants.WS_CONFIG_TYPE_OLD)
            || configurationTypes.contains(Constants.RS_CONFIG_TYPE)) {
            boolean jaxrs = isJaxrsRequested(configurationTypes, serviceProperties);
            return jaxrs ? jaxRsPojoConfigurationTypeHandler : pojoConfigurationTypeHandler;
        } else if (configurationTypes.contains(Constants.WSDL_CONFIG_TYPE)) {
            return wsdlConfigurationTypeHandler;
        }
        LOG.info("None of the configuration types in " + configurationTypes + " is supported.");
        return null;
    }

    private boolean isJaxrsRequested(Collection<String> types, Map<String, Object> serviceProperties) {
        if (types == null) {
            return false;
        }

        if (types.contains(Constants.RS_CONFIG_TYPE)) {
            Collection<String> intentsProperty
                = OsgiUtils.getMultiValueProperty(serviceProperties.get(RemoteConstants.SERVICE_EXPORTED_INTENTS));
            boolean hasHttpIntent = false;
            boolean hasSoapIntent = false;
            if (intentsProperty != null) {
                for (String intent : intentsProperty) {
                    if (intent.contains("SOAP")) {
                        hasSoapIntent = true;
                        break;
                    }

                    if (intent.contains("HTTP")) {
                        hasHttpIntent = true;
                    }
                }
            }
            if ((hasHttpIntent && !hasSoapIntent) || intentsProperty == null) {
                return true;
            }
        }
        return false;
    }

    /**
     * determine which configuration types should be used / if the requested are
     * supported
     */
    List<String> determineConfigurationTypes(Map<String, Object> serviceProperties) {
        String[] requestedConfigurationTypes = StringPlus.normalize(serviceProperties
                .get(RemoteConstants.SERVICE_EXPORTED_CONFIGS));
        if (requestedConfigurationTypes == null || requestedConfigurationTypes.length == 0) {
            return Collections.singletonList(DEFAULT_CONFIGURATION_TYPE);
        }

        List<String> configurationTypes = new ArrayList<String>();
        for (String rct : requestedConfigurationTypes) {
            if (configTypesSet.contains(rct)) {
                configurationTypes.add(rct);
            }
        }
        LOG.info("Configuration types selected for export: {}.", configurationTypes);
        return configurationTypes;
    }

    private List<String> determineConfigTypesForImport(EndpointDescription endpoint) {
        List<String> remoteConfigurationTypes = endpoint.getConfigurationTypes();

        List<String> usableConfigurationTypes = new ArrayList<String>();
        for (String ct : supportedConfigurationTypes) {
            if (remoteConfigurationTypes.contains(ct)) {
                usableConfigurationTypes.add(ct);
            }
        }

        LOG.info("Ignoring endpoint {} as it has no compatible configuration types: {}.", 
                 endpoint.getId(), remoteConfigurationTypes);
        return usableConfigurationTypes;
    }

    public String[] getSupportedTypes() {
        return supportedConfigurationTypes;
    }

}
