/*
* Copyright (c) 2016, 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.apimgt.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.util.AXIOMUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.impl.internal.ServiceReferenceHolder;
import org.wso2.carbon.event.throttle.core.ThrottlerService;
import org.wso2.carbon.event.throttle.core.exception.ThrottleConfigurationException;

public class ThrottlePolicyDeploymentManager {
    private static final Log log = LogFactory.getLog(ThrottlePolicyDeploymentManager.class);
    private static ThrottlePolicyDeploymentManager instance;
    private ThrottlerService throttler = ServiceReferenceHolder.getInstance().getThrottler();

    private ThrottlePolicyDeploymentManager() {
        APIManagerConfiguration config = ServiceReferenceHolder.getInstance().getAPIManagerConfigurationService()
                .getAPIManagerConfiguration();
        // get the gateway manager related configurations
    }

    public static synchronized ThrottlePolicyDeploymentManager getInstance() {
        if (instance == null) {
            instance = new ThrottlePolicyDeploymentManager();
        }
        return instance;
    }

    /**
     * Deploy policy in the global even processor
     * @param policy
     * @throws APIManagementException
     */
    public void deployPolicyToGlobalCEP(String policy) throws APIManagementException {
        try {
            OMElement element = AXIOMUtil.stringToOM(policy);
            String elegibilityQuery = element.getFirstChildWithName(new QName(APIConstants.ELIGIBILITY_QUERY_ELEM))
                    .getText();
            String decisionQuery = element.getFirstChildWithName(new QName(APIConstants.DECISION_QUERY_ELEM))
                    .getText();
            String fileName = element.getAttributeValue(new QName(APIConstants.POLICY_NAME_ELEM));
            //deploy to cep
            String policyQuery = elegibilityQuery + "\n" + decisionQuery;
            if(log.isDebugEnabled()){
                log.debug("deploy policy to global event processor : \n" + policyQuery );
            }
            throttler.deployGlobalThrottlingPolicy(fileName, policyQuery);
        } catch (XMLStreamException e) {
            String msg = "Error while parsing the policy to get the eligibility query: ";
            log.error(msg , e);
            throw new APIManagementException(msg);
        } catch (ThrottleConfigurationException e) {
            String msg = "Error while deploying policy to global event processor: ";
            log.error(msg , e);
            throw new APIManagementException(msg);
        }
    }

    /**
     * deploy policy in the gateway manager
     * @param policy
     * @throws APIManagementException
     */
    public void deployPolicyToGatewayManager(String policy) throws APIManagementException {
        OMElement element;
        try {
            element = AXIOMUtil.stringToOM(policy);
            String fileName = element.getAttributeValue(new QName(APIConstants.POLICY_NAME_ELEM));
            // TODO call gatewaymanager admin service to deploy.

            // Temp. save in local location
            writeToFile(policy, fileName);
        } catch (XMLStreamException e) {
            String msg = "Error while parsing the policy to get the eligibility query: ";
            log.error(msg , e);
            throw new APIManagementException(msg);
        } catch (IOException e) {
            String msg = "Error while deploying the policy in gateway manager: ";
            log.error(msg , e);
            throw new APIManagementException(msg);
        }
        
    }
    
    private void writeToFile(String content, String fileName) throws IOException {
        File file = new File(APIConstants.POLICY_FILE_FOLDER); // WSO2Carbon_Home/repository/deployment/server/throttle-config
        if (!file.exists()) { // if directory doesn't exist, make onee
            file.mkdir();
        }
        File writeFile = new File(APIConstants.POLICY_FILE_LOCATION + fileName); // file folder+/
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(writeFile);
            if (!writeFile.exists()) {
                writeFile.createNewFile();
            }
            byte[] contentInBytes = content.getBytes();
            fos.write(contentInBytes);
            fos.flush();
            fos.close();
        } catch (IOException e) {
            log.error("Error occurred writing to file: " + fileName, e);
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                log.error("Error occurred closing file output stream", e);
            }
        }
    }
}

@@ -706,73 +706,41 @@
 .io.
-File;%0Aimport java.io.FileOutputStream;%0Aimport java.io.IOException
+IOException;%0Aimport java.util.Map
 ;%0A%0Ai
@@ -1037,24 +1037,76 @@
 tException;%0A
+import org.wso2.carbon.apimgt.impl.dto.Environment;%0A
 import org.w
@@ -1161,16 +1161,80 @@
 Holder;%0A
+import org.wso2.carbon.apimgt.impl.utils.APIGatewayAdminClient;%0A
 import o
@@ -1666,16 +1666,67 @@
 ttler();
+%0A    private Map%3CString, Environment%3E environments;
 %0A%0A    pr
@@ -1940,57 +1940,58 @@
     
-// get the gateway manager related configurations
+environments = config.getApiGatewayEnvironments();
 %0A   
@@ -4076,148 +4076,421 @@
     
-// TODO call gatewaymanager admin service to deploy.%0A%0A            // Temp. save in local location%0A            writeToFile(policy, fileName);
+for (Map.Entry%3CString, Environment%3E environment : environments.entrySet()) %7B%0A                if(log.isDebugEnabled())%7B%0A                    log.debug(%22deploy policy to gateway : %22 + environment.getValue().getName());%0A                %7D%0A                APIGatewayAdminClient client = new APIGatewayAdminClient(null , environment.getValue());%0A                client.deployPolicy(policy, fileName);%0A            %7D%0A     
 %0A   
@@ -4927,1144 +4927,10 @@
    %7D
-%0A    %0A    private void writeToFile(String content, String fileName) throws IOException %7B%0A        File file = new File(APIConstants.POLICY_FILE_FOLDER); // WSO2Carbon_Home/repository/deployment/server/throttle-config%0A        if (!file.exists()) %7B // if directory doesn't exist, make onee%0A            file.mkdir();%0A        %7D%0A        File writeFile = new File(APIConstants.POLICY_FILE_LOCATION + fileName); // file folder+/%0A        FileOutputStream fos = null;%0A        try %7B%0A            fos = new FileOutputStream(writeFile);%0A            if (!writeFile.exists()) %7B%0A                writeFile.createNewFile();%0A            %7D%0A            byte%5B%5D contentInBytes = content.getBytes();%0A            fos.write(contentInBytes);%0A            fos.flush();%0A            fos.close();%0A        %7D catch (IOException e) %7B%0A            log.error(%22Error occurred writing to file: %22 + fileName, e);%0A        %7D finally %7B%0A            try %7B%0A                if (fos != null) %7B%0A                    fos.close();%0A                %7D%0A            %7D catch (IOException e) %7B%0A                log.error(%22Error occurred closing file output stream%22, e);%0A            %7D%0A        %7D%0A    %7D
+   
 %0A%7D%0A

deploy policy to manager node