/*
 * Copyright 2017 Hiroaki Kikuchi
 * exception handling is based on rundeck-slack-incoming-webhook-plugin from Andrew Karpow
 *
 *  Licensed 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 com.ketsuago.rundeck.plugins.webhook;

import com.dtolabs.rundeck.plugins.notification.NotificationPlugin;
import com.dtolabs.rundeck.core.plugins.Plugin;
import com.dtolabs.rundeck.plugins.descriptions.PluginDescription;
import com.dtolabs.rundeck.plugins.descriptions.PluginProperty;

import java.io.*;
import java.net.*;
import java.util.*;
import com.google.gson.Gson;

@Plugin(service="Notification",name="JsonWebhookNotification")
@PluginDescription(title="JSON Webhook", description="")
public class JsonWebhookNotificationPlugin implements NotificationPlugin {

    @PluginProperty(name = "webhookURL", title = "URL(s)", description = "Enter comma-separated URLs", required = true)
    private String STR_WEBHOOK_URL; // from GUI input

    public JsonWebhookNotificationPlugin() {
        // Do not remove constructor
    }

    public boolean postNotification(String trigger, Map executionData, Map config) {
        // merge trigger, executionData and config
        Map<String, Object> allData = new HashMap<>();
        allData.put("trigger", trigger);
        allData.put("execution", executionData);
        allData.put("config", config);

        // convert map to json
        Gson gson = new Gson();
        String executionJson = gson.toJson(allData);

        // post json to URLs
        List<HttpResponse> failedResponses = new ArrayList<>();

        List<String> webhookUrls = Arrays.asList(STR_WEBHOOK_URL.split(","));
        for (String url: webhookUrls) {
            url = url.trim();
            HttpResponse response = postWebhook(url, executionJson);
            if (response.getCode() != HttpURLConnection.HTTP_OK) {
                failedResponses.add(response);
            }
        }
        if (!failedResponses.isEmpty()) {
            StringBuilder sb = new StringBuilder();
            for (HttpResponse res: failedResponses) {
                sb.append(res.getUrl())
                        .append(", server response ")
                        .append(res.getCode())
                        .append(", ")
                        .append(res.getMessage())
                        .append("; ");
            }
            // TODO: refactor
            sb.deleteCharAt(sb.length()-1);
            sb.deleteCharAt(sb.length()-1);
            throw new JsonWebhookNotificationPluginException("Failed to POST to following URLs: " + sb.toString());
        }
        return true;
    }


    private HttpResponse postWebhook(String strUrl, String message) {
        HttpURLConnection con = null;
        try {
            URL url = toURL(strUrl);
            con = openConnection(url);
            con.setDoOutput(true);
            putRequestStream(con, message);
            con.connect();

            return new HttpResponse(strUrl, con.getResponseCode(), con.getResponseMessage());
        } catch (IOException e) {
            throw new JsonWebhookNotificationPluginException("Error opening connection: [" + e.getMessage() + "]", e);
        } finally {
            if (con != null) {
                con.disconnect();
            }
        }
    }

    private URL toURL(String str) {
        try {
            return new URL(str);
        } catch (MalformedURLException e) {
            throw new JsonWebhookNotificationPluginException("Webhook URL is malformed: [" + e.getMessage() +"]", e);
        }
    }

    private HttpURLConnection openConnection(URL url) {
        try {
            return (HttpURLConnection) url.openConnection();
        } catch (IOException e) {
            throw new JsonWebhookNotificationPluginException("Error opening connection: [" + e.getMessage() + "]", e);
        }
    }

    private void putRequestStream(HttpURLConnection con, String message) {
        try {
            con.setRequestMethod("POST");
            con.setRequestProperty("Content-Type", "application/json");
            OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream());
            out.write(message);
            out.close();
        } catch (ProtocolException e) {
            throw new JsonWebhookNotificationPluginException("Error in the underlying protocol: [" + e.getMessage() + "]", e);
        } catch (IOException e) {
            throw new JsonWebhookNotificationPluginException("Error putting data to Webhook URL: [" + e.getMessage() + "]", e);
        }
    }
}

@@ -987,17 +987,16 @@
 operty;%0A
-%0A
 import j
@@ -1327,55 +1327,8 @@
 %22URL
-(s)%22, description = %22Enter comma-separated URLs
 %22, r
@@ -1950,15 +1950,15 @@
 son 
-to URLs
+webhook
 %0A   
@@ -1962,21 +1962,16 @@
         
-List%3C
 HttpResp
@@ -1978,247 +1978,47 @@
 onse
-%3E failedR
+ r
 esponse
-s
  = 
-new ArrayList%3C%3E();%0A%0A        List%3CString%3E webhookUrls = Arrays.asList(STR_WEBHOOK_URL.split(%22,%22));%0A        for (String url: webhookUrls) %7B%0A            url = url.trim();%0A            HttpResponse response = postWebhook(url
+postWebhook(STR_WEBHOOK_URL
 , ex
@@ -2035,28 +2035,24 @@
 n);%0A        
-   
- 
 if (response
@@ -2110,254 +2110,119 @@
     
-    failedResponses.add(response);%0A            %7D%0A        %7D%0A        if (!failedResponses.isEmpty()) %7B%0A            StringBuilder sb = new StringBuilder();%0A            for (HttpResponse res: failedResponses) %7B%0A                sb.append(res.getUrl())
+throw new JsonWebhookNotificationPluginException(%22URL %22 + STR_WEBHOOK_URL + %22: Unable to POST notification: %22 +
 %0A   
@@ -2238,31 +2238,17 @@
         
-    .append(%22, 
+%22
 server r
@@ -2258,429 +2258,60 @@
 onse
+:
  %22
-)%0A                        .append(res.getCode())%0A                        .append(%22, %22)%0A                        .append(res.getMessage())%0A                        .append(%22; %22);%0A            %7D%0A            // TODO: refactor%0A            sb.deleteCharAt(sb.length()-1);%0A            sb.deleteCharAt(sb.length()-1);%0A            throw new JsonWebhookNotificationPluginException(%22Failed to POST to following URLs: %22 + sb.toString
+ + response.getCode() + %22 %22 + response.getMessage
 ());

Make it back to posting to single URL