// Licensed to the Apache Software Foundation (ASF) under one or more contributor
// license agreements; and to You under the Apache License, Version 2.0.

 /**
  *
  * main() will be invoked when you Run This Action.
  *
  * @param Whisk actions accept a single parameter,
  *        which must be a JSON object.
  *
  * In this case, the params variable will look like:
  *     {
  *         "prs": "xxxx",
  *         "slack_package": "xxxx",
  *     }
  *
  * @return which must be a JSON object.
  *         It will be the output of this action.
  *
  */

function main(params) {
    // require the OpenWhisk npm package
    var openwhisk = require("openwhisk");

    // instantiate the openwhisk instance before you can use it
    wsk = openwhisk();

    //read Params
    var prs = params.prs;
    var slackPackage = params.slack_package;

    if (prs.length === 0) {
        return {
            message: "Yeay! No old PRs!"
        };
    }

    var messages = ["Hello Whisk Devs! It looks like we have some Pull Requests that may require a little love:\n"];

    prs.sort(byDescendingAge);

    for (var i = 0; i < prs.length; i++) {
        // read pr from a document
        var doc = prs[i];
        var pr = doc.pr;
        console.log("PR:" + doc._id);
        // find out how many days old a pull request is.
        var age = getPrAge(doc, "days");
        var ageString = age + " " + (age === 1 ? "day" : "days");
        var message;
        if(doc.state === "READY") {
            message = "has been marked \"ready\" for more than " + ageString
        } else {
            message = "has been under \"review\" without comments for more than " + ageString
        }
        messages.push("<" + pr["html_url"] + "|[" + pr.base.repo["full_name"] + "] PR #" + pr.number + "> " + message);
    }

    console.log(messages.join("\n"));

    // access namespace as environment variables
    var namespace = process.env["__OW_NAMESPACE"];

    // Slack package can be accessed using /namespace/package
    packageName = "/" + namespace + "/" + slackPackage;

    return wsk.actions.invoke({
        actionName: packageName + "/post",
        params: {
            "text": messages.join("\n"),
        },
        blocking: true
    })
    .then(activation => {
        console.log("Posted messages to slack");
        return {
            message: activation
        };
    })
    .catch(function (err) {
        console.log("Error posting messages to slack")
        return {
            error: err
        };
    });
}

function byDescendingAge(pr1, pr2) {
    var age1 = getPrAge(pr1, "hours");
    var age2 = getPrAge(pr2, "hours");
    // sort descending
    return age2 - age1;
}

function getPrAge(pr, unit) {
    var moment = require("moment");
    // instantiate moment with last update of a pull request
    var readyMoment = moment(pr.lastUpdate);
    // difference between now and last update in "hours" or "days"
    return moment().diff(readyMoment, unit);
}
