package com.tw.go.plugin;

import com.google.gson.GsonBuilder;
import com.thoughtworks.go.plugin.api.GoApplicationAccessor;
import com.thoughtworks.go.plugin.api.GoPlugin;
import com.thoughtworks.go.plugin.api.GoPluginIdentifier;
import com.thoughtworks.go.plugin.api.annotation.Extension;
import com.thoughtworks.go.plugin.api.logging.Logger;
import com.thoughtworks.go.plugin.api.request.GoPluginApiRequest;
import com.thoughtworks.go.plugin.api.response.GoPluginApiResponse;

import java.util.*;

import static java.util.Arrays.asList;

@Extension
public class EmailNotificationPluginImpl implements GoPlugin {
    private static Logger LOGGER = Logger.getLoggerFor(EmailNotificationPluginImpl.class);

    public static final String EXTENSION_NAME = "notification";
    private static final List<String> goSupportedVersions = asList("1.0");

    public static final String REQUEST_NOTIFICATIONS_INTERESTED_IN = "notifications-interested-in";
    public static final String REQUEST_STAGE_STATUS = "stage-status";

    public static final int SUCCESS_RESPONSE_CODE = 200;
    public static final int INTERNAL_ERROR_RESPONSE_CODE = 500;

    @Override
    public void initializeGoApplicationAccessor(GoApplicationAccessor goApplicationAccessor) {
        // ignore
    }

    @Override
    public GoPluginApiResponse handle(GoPluginApiRequest goPluginApiRequest) {
        if (goPluginApiRequest.requestName().equals(REQUEST_NOTIFICATIONS_INTERESTED_IN)) {
            return handleNotificationsInterestedIn();
        } else if (goPluginApiRequest.requestName().equals(REQUEST_STAGE_STATUS)) {
            return handleStageNotification(goPluginApiRequest);
        }
        return null;
    }

    @Override
    public GoPluginIdentifier pluginIdentifier() {
        return new GoPluginIdentifier(EXTENSION_NAME, goSupportedVersions);
    }

    private GoPluginApiResponse handleNotificationsInterestedIn() {
        Map<String, Object> response = new HashMap<String, Object>();
        response.put("notifications", Arrays.asList(REQUEST_STAGE_STATUS));
        return renderJSON(SUCCESS_RESPONSE_CODE, response);
    }

    private GoPluginApiResponse handleStageNotification(GoPluginApiRequest goPluginApiRequest) {
        Map<String, Object> dataMap = getMapFor(goPluginApiRequest);

        int responseCode = SUCCESS_RESPONSE_CODE;
        Map<String, Object> response = new HashMap<String, Object>();
        List<String> messages = new ArrayList<String>();
        try {
            String subject = "Stage: " + dataMap.get("pipeline-name") + "/" + ((Double) dataMap.get("pipeline-counter")).intValue() + "/" + dataMap.get("stage-name") + "/" + dataMap.get("stage-counter");
            String body = "State: " + dataMap.get("stage-state") + "\nResult: " + dataMap.get("stage-result") + "\nCreate Time: " + dataMap.get("create-time");

            LOGGER.warn("Sending Email for " + subject);

            SMTPSettings settings = new SMTPSettings("smtp.gmail.com", 587, true, "", "");
            new SMTPMailSender(settings).send(subject, body, "");

            LOGGER.warn("Done");

            response.put("status", "success");
            messages.add("Could connect to URL successfully");
        } catch (Exception e) {
            responseCode = INTERNAL_ERROR_RESPONSE_CODE;
            response.put("status", "failure");
            messages.add(e.getMessage());
        }

        response.put("messages", messages);
        return renderJSON(responseCode, response);
    }

    private Map<String, Object> getMapFor(GoPluginApiRequest goPluginApiRequest) {
        return (Map<String, Object>) new GsonBuilder().create().fromJson(goPluginApiRequest.requestBody(), Object.class);
    }

    private GoPluginApiResponse renderJSON(final int responseCode, Object response) {
        final String json = response == null ? null : new GsonBuilder().create().toJson(response);
        return new GoPluginApiResponse() {
            @Override
            public int responseCode() {
                return responseCode;
            }

            @Override
            public Map<String, String> responseHeaders() {
                return null;
            }

            @Override
            public String responseBody() {
                return json;
            }
        };
    }
}

@@ -2494,189 +2494,335 @@
     
+Map%3C
 String
- su
+, O
 bject
- = %22Stage: %22 + dataMap.get(%22pipeline-name%22) + %22/%22 + ((Double) dataMap.get(%22pipeline-counter%22)).intValue() + %22/%22 + dataMap.get(%22stage-name%22) + %22/%22 + dataMap.get(%22stage-
+%3E pipelineMap = (Map%3CString, Object%3E) dataMap.get(%22pipeline%22);%0A            Map%3CString, Object%3E stageMap = (Map%3CString, Object%3E) pipelineMap.get(%22stage%22);%0A%0A            String subject = String.format(%22Stage: %25s/%25s/%25s/%25s%22, pipelineMap.get(%22name%22), pipelineMap.get(%22counter%22), stageMap.get(%22name%22), stageMap.get(%22
 coun
@@ -2826,16 +2826,17 @@
 ounter%22)
+)
 ;%0A      
@@ -2859,68 +2859,118 @@
 y = 
-%22State: %22 + dataMap.get(%22stage-state%22) + %22%5CnResult: %22 + data
+String.format(%22State: %25s%5CnResult: %25s%5CnCreate Time: %25s%5CnLast Transition Time: %25s%22, stageMap.get(%22state%22), stage
 Map.
@@ -2978,22 +2978,16 @@
 et(%22
-stage-
 result%22)
  + %22
@@ -2986,57 +2986,76 @@
 lt%22)
- + %22%5CnC
+, stageMap.get(%22c
 reate
- Time: %22 + dataMap.get(%22create
+-time%22), stageMap.get(%22last-transition
 -time%22)
+)
 ;%0A%0A 
@@ -3362,94 +3362,111 @@
     
-    messages.add(%22Could connect to URL successfully%22);%0A        %7D catch (Exception e) %7B
+%7D catch (Exception e) %7B%0A            LOGGER.warn(%22Error occurred while trying to deliver an email.%22, e);
 %0A   
@@ -3562,24 +3562,72 @@
 %22failure%22);%0A
+            if (!isEmpty(e.getMessage())) %7B%0A    
             
@@ -3652,24 +3652,38 @@
 Message());%0A
+            %7D%0A
         %7D%0A%0A 
@@ -3775,32 +3775,133 @@
 sponse);%0A    %7D%0A%0A
+    private boolean isEmpty(String str) %7B%0A        return str == null %7C%7C str.trim().isEmpty();%0A    %7D%0A%0A
     private Map%3C

handle api update + cleanup