/*
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.wso2.carbon.identity.application.authentication.framework.listener;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.identity.application.authentication.framework.config.ConfigurationFacade;
import org.wso2.carbon.stratos.common.beans.TenantInfoBean;
import org.wso2.carbon.stratos.common.exception.StratosException;
import org.wso2.carbon.stratos.common.listeners.TenantMgtListener;
import org.wso2.carbon.ui.CarbonUIUtil;
import org.wso2.carbon.user.api.Tenant;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.core.service.RealmService;
import org.wso2.carbon.user.core.tenant.TenantManager;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;

/**
 * Class for listening to modifications of tenants and sending the tenant list to receiving endpoints.
 */
public class AuthenticationEndpointTenantActivityListener implements TenantMgtListener {

    /**
     * Logger for the class
     */
    private static final Log log = LogFactory.getLog(AuthenticationEndpointTenantActivityListener.class);

    /**
     * URL Root
     */
    private static final String URL_ROOT = "/";

    /**
     * Carbon server URL path
     */
    private static final String CARBON_PATH = "/carbon/";

    /**
     * Empty string
     */
    private static final String EMPTY_STRING = "";

    /**
     * Tenant list query parameter
     */
    private static final String TENANT_LIST_QUERY_PARAM = "tenantList";

    /**
     * Tenant list data separator
     */
    private static final String TENANT_LIST_DATA_SEPARATOR = ",";

    /**
     * List of tenant list receiving URLs
     */
    private List<String> tenantDataReceiveURLs;

    /**
     * TenantManager for receiving tenant data
     */
    private TenantManager tenantManager;

    /**
     * Listener initialization status
     */
    private boolean initialized;

    /**
     * CARBON SERVER URL
     */
    private String serverURL;

    /**
     * Initialize listener
     */
    private synchronized void init() {
        try {
            tenantDataReceiveURLs = ConfigurationFacade.getInstance().getTenantDataEndpointURLs();

            if (!tenantDataReceiveURLs.isEmpty()) {

                serverURL = CarbonUIUtil.getAdminConsoleURL(URL_ROOT).replace(CARBON_PATH, EMPTY_STRING);
                int index = 0;

                for (String tenantDataReceiveUrl : tenantDataReceiveURLs) {
                    URI tenantDataReceiveURI = new URI(tenantDataReceiveUrl);

                    if (log.isDebugEnabled()) {
                        log.debug("Tenant list receiving url added : " + tenantDataReceiveUrl);
                    }

                    if (!tenantDataReceiveURI.isAbsolute()) {
                        // Set the absolute URL for tenant list receiving endpoint
                        tenantDataReceiveURLs.set(index, serverURL + tenantDataReceiveUrl);
                    }
                    index++;
                }
                RealmService realmService = (RealmService) PrivilegedCarbonContext.getThreadLocalCarbonContext()
                        .getOSGiService(RealmService.class);

                if (realmService != null) {
                    tenantManager = realmService.getTenantManager();
                }
                initialized = true;
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("TenantDataListenerURLs are not set in configuration");
                }
            }
        } catch (URISyntaxException e) {
            log.error("Error while getting TenantDataListenerURLs", e);
        }
    }

    /**
     * Send the list of tenants to the receiving endpoints
     */
    private void sendTenantList() {

        if (!initialized) {
            init();
        }

        if (!initialized) {
            if (log.isDebugEnabled()) {
                log.debug("AuthenticationEndpointTenantActivityListener is not initialized. Tenant list not sent " +
                        "to authentication endpoint");
            }
            return;
        }

        if (tenantDataReceiveURLs != null && tenantDataReceiveURLs.size() > 0) {
            Tenant[] tenants = new Tenant[0];
            try {
                tenants = tenantManager.getAllTenants();
            } catch (UserStoreException e) {
                log.error("Retrieving all available tenants failed", e);
            }
            StringBuilder tenantDataReceiverUrlBuilder = new StringBuilder();
            // Add only the active tenants to the list
            for (Tenant tenant : tenants) {
                if (tenant.isActive()) {
                    tenantDataReceiverUrlBuilder.append(tenant.getDomain() + TENANT_LIST_DATA_SEPARATOR);
                }
            }
            if (tenantDataReceiverUrlBuilder.toString().length() > 0) {
                // Delete data separator at the last index
                tenantDataReceiverUrlBuilder.deleteCharAt(tenantDataReceiverUrlBuilder.toString().length() - 1);
            }

            StringBuilder paramsBuilder = new StringBuilder();
            paramsBuilder.append("?").append(TENANT_LIST_QUERY_PARAM).append("=")
                    .append(tenantDataReceiverUrlBuilder.toString());

            InputStream inputStream = null;
            for (String tenantDataReceiveURL : tenantDataReceiveURLs) {
                try {
                    // Send tenant list to the receiving endpoint
                    inputStream = new URL(tenantDataReceiveURL + paramsBuilder.toString()).openStream();

                } catch (IOException e) {
                    log.error("Sending tenant domain list to " + tenantDataReceiveURL + " failed.", e);

                } finally {
                    if (inputStream != null) {
                        try {
                            inputStream.close();
                        } catch (IOException e) {
                            log.error("Error while closing the tenant data receiving stream", e);
                        }
                    }
                }
            }
        }
    }

    @Override
    public void onTenantInitialActivation(int tenantId) throws StratosException {
        sendTenantList();
    }

    @Override
    public void onTenantActivation(int tenantId) throws StratosException {
        sendTenantList();
    }

    @Override
    public void onTenantDeactivation(int tenantId) throws StratosException {
        sendTenantList();
    }

    @Override
    public void onTenantCreate(TenantInfoBean tenantInfoBean) throws StratosException {

    }

    @Override
    public void onTenantUpdate(TenantInfoBean tenantInfoBean) throws StratosException {

    }

    @Override
    public void onPreDelete(int tenantId) throws StratosException {

    }

    @Override
    public void onTenantDelete(int tenantId) {

    }

    @Override
    public void onTenantRename(int tenantId, String oldDomainName, String newDomainName) throws StratosException {

    }

    @Override
    public void onSubscriptionPlanChange(int tenentId, String oldPlan, String newPlan) throws StratosException {

    }

    @Override
    public int getListenerOrder() {
        return 0;
    }

	@Override
	public void onPreDelete(int tenantId) throws StratosException {
		// Implement this method to delete product specific data
	}
}

@@ -8052,144 +8052,6 @@
  %7D%0A%0A
-%09@Override%0A%09public void onPreDelete(int tenantId) throws StratosException %7B%0A%09%09// Implement this method to delete product specific data%0A%09%7D%0A
 %7D%0A

fix compilation faliure