// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package com.uber.jenkins.phabricator.tasks;

import com.uber.jenkins.phabricator.CommentBuilder;
import com.uber.jenkins.phabricator.conduit.ArcanistUsageException;
import com.uber.jenkins.phabricator.conduit.DifferentialClient;
import com.uber.jenkins.phabricator.utils.Logger;
import net.sf.json.JSONNull;
import net.sf.json.JSONObject;

import java.io.IOException;

/**
 * Post comment task.
 */
public class PostCommentTask extends Task {

    private static final boolean SILENT = false;
    private static final String DEFAULT_COMMENT_ACTION = "none";

    private DifferentialClient differentialClient;
    private String commentAction;
    private String comment;

    /**
     * PostCommentTask constructor.
     * @param logger The logger.
     */
    public PostCommentTask(Logger logger, DifferentialClient differentialClient,
                           String commentAction,
                           CommentBuilder commentBuilder,
                           boolean commentWithConsoleLinkOnFailure,
                           hudson.model.Result buildResult) {
        super(logger);

        this.differentialClient = differentialClient;
        this.commentAction = commentAction;

        if (commentWithConsoleLinkOnFailure &&
                buildResult.isWorseOrEqualTo(hudson.model.Result.UNSTABLE)) {
            commentBuilder.addBuildFailureMessage();
        } else {
            commentBuilder.addBuildLink();
        }

        comment = commentBuilder.getComment();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected String getTag() {
        return "post-comment";
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void setup() {
        // Do nothing.
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void execute() {
        JSONObject result = postDifferentialComment(comment, SILENT, commentAction);
        if (!(result.get("errorMessage") instanceof JSONNull)) {
            info("Get error " + result.get("errorMessage") + " with action " +
                    commentAction + "; trying again with action 'none'");
            postDifferentialComment(comment, SILENT, DEFAULT_COMMENT_ACTION);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void tearDown() {
        // Do nothing.
    }

    private JSONObject postDifferentialComment(String message, boolean silent, String action) {
        try {
            return differentialClient.postComment(message, silent, action);
        } catch (ArcanistUsageException e) {
            info("unable to post comment");
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        return null;
    }
}

@@ -3101,19 +3101,33 @@
 nfo(
+String.format(
 %22G
-e
+o
 t error 
 %22 + 
@@ -3126,42 +3126,36 @@
 ror 
-%22 + result.get(%22errorMessage%22) + %22
+%25s with action %25s. Re-trying
  wit
@@ -3167,11 +3167,16 @@
 ion 
-%22 +
+'none'%22,
 %0A   
@@ -3196,59 +3196,50 @@
     
-commentAction + %22; trying again with action 'none'%22
+result.get(%22errorMessage%22), commentAction)
 );%0A 

Update comment posting failure log