/*
# Licensed Materials - Property of IBM
# Copyright IBM Corp. 2015  
 */
package com.ibm.streamsx.topology.internal.context;

import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Map;
import java.util.concurrent.Future;

import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import com.google.gson.JsonObject;
import com.ibm.json.java.JSONObject;
import com.ibm.streamsx.topology.Topology;
import com.ibm.streamsx.topology.context.AnalyticsServiceProperties;
import com.ibm.streamsx.topology.context.remote.RemoteContext;
import com.ibm.streamsx.topology.internal.process.CompletedFuture;
import com.ibm.streamsx.topology.internal.streaminganalytics.RestUtils;
import com.ibm.streamsx.topology.internal.streaminganalytics.VcapServices;
import com.ibm.streamsx.topology.internal.streams.JobConfigOverlay;
import com.ibm.streamsx.topology.jobconfig.JobConfig;

public class AnalyticsServiceStreamsContext extends
        BundleUserStreamsContext<BigInteger> {

    public AnalyticsServiceStreamsContext() {
        super(false);
    }

    @Override
    public Type getType() {
        return Type.ANALYTICS_SERVICE;
    }

    @Override
    public Future<BigInteger> submit(Topology app, Map<String, Object> config)
            throws Exception {

        preBundle(config);
        File bundle = bundler.submit(app, config).get();

        preInvoke();

        BigInteger jobId = submitJobToService(bundle, config);
        
        return new CompletedFuture<BigInteger>(jobId);
    }

    @Override
    public Future<BigInteger> submit(JSONObject submission) throws Exception {
        Map<String, Object> config = Contexts
                .jsonDeployToMap((JSONObject) submission.get(RemoteContext.SUBMISSION_DEPLOY));

        preBundle(config);
        File bundle = bundler.submit(submission).get();
        preInvoke();

        BigInteger jobId = submitJobToService(bundle, config);

        return new CompletedFuture<BigInteger>(jobId);
    }

    void preInvoke() {
        
    }
    
    /**
     * Verify we have a valid Streaming Analytic service
     * information before we attempt anything.
     */
    void preBundle(Map<String, Object> config) {
        try {
            getVCAPService(config);
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }
    }
    
    JsonObject getVCAPService(Map<String, Object> config) throws IOException {
        // Convert from JSON4J to a string since the common code
        // does not reference JSON4J
        Object vco = config.get(AnalyticsServiceProperties.VCAP_SERVICES);
        if (vco instanceof JSONObject) {
            JSONObject servicej = (JSONObject) vco;
            config.put(AnalyticsServiceProperties.VCAP_SERVICES, servicej.serialize());           
        }
        return VcapServices.getVCAPService(key -> config.get(key));
    }  
   
    private JsonObject getBluemixSubmitConfig( Map<String, Object> config) throws IOException {
        
        JobConfig jc = JobConfig.fromProperties(config);
        
        // Streaming Analytics service is always using 4.2 or later
        // so use the job config overlay
            
        JobConfigOverlay jco = new JobConfigOverlay(jc);
        
        return jco.fullOverlayAsJSON();
    }
    
    private BigInteger submitJobToService(File bundle, Map<String, Object> config) throws IOException {
        
        final JsonObject serviceg = getVCAPService(config);
        JSONObject service = JSONObject.parse(serviceg.toString()); //temp            
              
        final JsonObject credentials = serviceg.getAsJsonObject("credentials");
        
        final CloseableHttpClient httpClient = HttpClients.createDefault();
        try {
            Topology.STREAMS_LOGGER.info("Streaming Analytics Service: Checking status :" + service.get("name"));
            
            RestUtils.checkInstanceStatus(httpClient, credentials);
            
            Topology.STREAMS_LOGGER.info("Streaming Analytics Service: Submitting bundle : " + bundle.getName() + " to " + service.get("name"));
            
            JsonObject jcojson = getBluemixSubmitConfig(config);
            
            Topology.STREAMS_LOGGER.info("Streaming Analytics Service submit job request:" + jcojson.toString());

            return RestUtils.postJob(httpClient, credentials, bundle, jcojson);
        } finally {
            httpClient.close();
        }
    }
}

@@ -121,16 +121,94 @@
 ntext;%0A%0A
+import static com.ibm.streamsx.topology.internal.gson.GsonUtilities.jstring;%0A%0A
 import j
@@ -3582,17 +3582,16 @@
  service
-g
  = getVC
@@ -3621,86 +3621,60 @@
     
-JSONObject service = JSONObject.parse(serviceg.toString()); //temp            
+final String serviceName = jstring(service, %22name%22);
 %0A   
@@ -3731,17 +3731,16 @@
  service
-g
 .getAsJs
@@ -3958,36 +3958,28 @@
 :%22 + service
-.get(%22n
+N
 ame
-%22)
 );%0A         
@@ -4197,20 +4197,12 @@
 vice
-.get(%22n
+N
 ame
-%22)
 );%0A 

Remove last use of JSON4J in job submission