/*
 *  Copyright (c) 2020, 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.gatewayartifactsynchronizer;


import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.impl.APIManagerConfiguration;
import org.wso2.carbon.apimgt.impl.dao.ApiMgtDAO;
import org.wso2.carbon.apimgt.impl.gatewayartifactsynchronizer.exception.ArtifactSynchronizerException;
import org.wso2.carbon.apimgt.impl.internal.ServiceReferenceHolder;
import org.wso2.carbon.apimgt.impl.utils.APIUtil;
import java.io.IOException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

public class DBRetriever implements ArtifactRetriever {

    private static final Log log = LogFactory.getLog(DBRetriever.class);
    protected ApiMgtDAO apiMgtDAO = ApiMgtDAO.getInstance();

    @Override
    public void init() throws ArtifactSynchronizerException {
        //not required
    }

    @Override
    public String retrieveArtifact(String APIId, String gatewayLabel, String gatewayInstruction)
            throws ArtifactSynchronizerException {
        try {
            String baseURL = APIConstants.HTTPS_PROTOCOL_URL_PREFIX +
                    System.getProperty(APIConstants.KEYMANAGER_HOSTNAME) + ":" +
                    System.getProperty(APIConstants.KEYMANAGER_PORT) + APIConstants.INTERNAL_WEB_APP_EP;
            String endcodedgatewayLabel= URLEncoder.encode(gatewayLabel, APIConstants.DigestAuthConstants.CHARSET);
            String path  = APIConstants.GatewayArtifactSynchronizer.SYNAPSE_ARTIFACTS + "?apiId=" + APIId +
                    "&gatewayInstruction=" + gatewayInstruction +"&gatewayLabel="+ endcodedgatewayLabel;
            String endpoint = baseURL + path;
            HttpResponse httpResponse = invokeService(endpoint);
            if (httpResponse.getEntity() != null ){
                return EntityUtils.toString(httpResponse.getEntity(), APIConstants.DigestAuthConstants.CHARSET);
            } else {
                throw new ArtifactSynchronizerException("HTTP response is empty");
            }
        } catch (IOException e) {
            String msg = "Error while executing the http client " ;
            log.error(msg, e);
            throw new ArtifactSynchronizerException(msg, e);
        }
    }

    @Override
    public List<String> retrieveAllArtifacts(String label) throws ArtifactSynchronizerException {
        List<String> gatewayRuntimeArtifactsArray = new ArrayList<>();
        try {
            String baseURL = APIConstants.HTTPS_PROTOCOL_URL_PREFIX +
                    System.getProperty(APIConstants.KEYMANAGER_HOSTNAME) + ":" +
                    System.getProperty(APIConstants.KEYMANAGER_PORT) + APIConstants.INTERNAL_WEB_APP_EP;
            String endcodedgatewayLabel= URLEncoder.encode(label, APIConstants.DigestAuthConstants.CHARSET);
            String path  = APIConstants.GatewayArtifactSynchronizer.GATEAY_SYNAPSE_ARTIFACTS
                    + "?gatewayLabel="+ endcodedgatewayLabel;
            String endpoint = baseURL + path;
            HttpResponse httpResponse = invokeService(endpoint);
            String responseString;
            if (httpResponse.getEntity() != null ){
                responseString = EntityUtils.toString(httpResponse.getEntity(),
                        APIConstants.DigestAuthConstants.CHARSET);
            } else {
                throw new ArtifactSynchronizerException("HTTP response is empty");
            }
            JSONObject artifactObject = new JSONObject(responseString);
            JSONArray jArray = (JSONArray)artifactObject.get("list");
            if (jArray != null) {
                for (int i = 0; i < jArray.length(); i++) {
                    gatewayRuntimeArtifactsArray.add(jArray.get(i).toString());
                }
            }
            return gatewayRuntimeArtifactsArray;
        } catch (IOException e) {
            String msg = "Error while executing the http client " ;
            log.error(msg, e);
            throw new ArtifactSynchronizerException(msg, e);
        }
    }

    private HttpResponse invokeService(String endpoint) throws IOException, ArtifactSynchronizerException {
        HttpGet method = new HttpGet(endpoint);
        URL synapseGetURL = new URL(endpoint);
        APIManagerConfiguration config = ServiceReferenceHolder.getInstance()
                .getAPIManagerConfigurationService().getAPIManagerConfiguration();
        String username = config.getFirstProperty(APIConstants.API_KEY_VALIDATOR_USERNAME);
        String password = config.getFirstProperty(APIConstants.API_KEY_VALIDATOR_PASSWORD);
        byte[] credentials = Base64.encodeBase64((username + ":" + password).getBytes
                (APIConstants.DigestAuthConstants.CHARSET));
        int synapsePort = synapseGetURL .getPort();
        String synapseProtocol = synapseGetURL .getProtocol();
        method.setHeader("Authorization", "Basic " + new String(credentials,
                APIConstants.DigestAuthConstants.CHARSET));
        HttpClient httpClient = APIUtil.getHttpClient(synapsePort, synapseProtocol);
        return  APIUtil.executeHTTPRequest(method, httpClient);
    }

    @Override
    public void disconnect() {
        //not required
    }

    @Override
    public String getName() {

        return APIConstants.GatewayArtifactSynchronizer.DB_RETRIEVER_NAME;
    }
}

@@ -4934,35 +4934,33 @@
  the http client
- %22 
+%22
 ;%0A            lo
@@ -5132,39 +5132,8 @@
 tion
-, ArtifactSynchronizerException
  %7B%0A 

resolve formatting issues