/*
 * Copyright (C) 2020 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

import {stat} from "fs";
import path from "path";
import util from "util";
import {execFile, spawn} from "child_process";
import SlackRTMAPI from "@slack/rtm-api";
import AsyncTaskQueue from "./AsyncTaskQueue.mjs";
import {dataLogLn, escapeForSlackText, isASCII, rootDirectoryOfWebKit} from "./Utility.mjs";

const defaultTaskLimit = 10;
const defaultPullPeriod = 60 * 1000 * 60;
const defaultTimeoutForRevert = 60 * 1000 * 10;

const execFileAsync = util.promisify(execFile);
const statAsync = util.promisify(stat);

function parseBugId(string)
{
    if (!string)
        return null;

    let match = string.match(/^https?:\/\/webkit\.org\/b\/(\d+)$/m);
    if (match)
        return match[1];

    match = string.match(/^https?:\/\/bugs\.webkit\.org\/show_bug\.cgi\?id=(\d+)(?:&ctype=xml|&excludefield=attachmentdata)*$/m);
    if (match)
        return match[1];

    return null;
}

function extractRevision(text)
{
    let revisions = [];
    for (let candidate of text.split(",")) {
        candidate = candidate.trim();
        if (!candidate)
            continue;

        let match = candidate.match(/^r?(\d+):?$/);
        if (!match)
            return null;

        revisions.push(match[1]);
    }
    return revisions;
}

export function extractRevisionsAndReason(args)
{
    let revisions = [];
    let reason = "";
    for (let i = 0; i < args.length; ++i) {
        let arg = args[i];
        let extracted = extractRevision(arg);
        if (!extracted) {
            let reasons = [];
            for (; i < args.length; ++i)
                reasons.push(args[i]);
            reason = reasons.join(" ").trim();
            break;
        }
        revisions.push(...extracted);
    }

    // If reason starts with quote and ends with the same quote, remove them once.
    if (reason.length >= 2) {
        let firstCharacterOfReason = reason.charAt(0);
        if (firstCharacterOfReason === "'" || firstCharacterOfReason === "\"" || firstCharacterOfReason === "`") {
            if (reason.charAt(reason.length - 1) === firstCharacterOfReason)
                reason = reason.slice(1, reason.length - 1);
        }
    }

    return {revisions, reason};
}

export function extractCommandAndArgs(text)
{
    let args = text.trim().split(/\s+/);
    let command = args.shift().toLowerCase();
    return {command, args};
}

export function extractTextIfMentioned(text, id)
{
    let regexp = new RegExp(`<@${id}>`);
    let globalRegexp = new RegExp(`<@${id}>`, "g");
    let matched = text.match(regexp);
    if (!matched)
        return null;

    text = text.replace(globalRegexp, "");

    // Preprocessing for the text.
    // 1. Convert smart quotes to normal ASCII quotes because webkit-patch cannot accept non-ASCII text and slack may convert normal quotes to smart quotes.
    text = text.replace(/[\u2018\u2019]/g, "'");
    text = text.replace(/[\u201C\u201D]/g, "\"");

    // 2. Convert line-terminators to spaces. It is unlikely that we want to have line-terminators in webkitbot commands.
    text = text.replace(/(\r\n|\n|\r|\u2028|\u2029)/g, " ");

    return text;
}

export default class WebKitBot {
    constructor(webClient, auth)
    {
        this._taskQueue = new AsyncTaskQueue(defaultTaskLimit);
        this._web = webClient;
        this._auth = auth;

        this._commands = new Map;

        let revertCommand = {
            description: "Opens a bug to revert the specified revision, CCing author + reviewer, and attaching the reverse-diff of the given revisions marked as commit-queue=?.",
            usage: `\`revert SVN_REVISION [SVN_REVISIONS] REASON\`
e.g. \`revert 260220 Ensure it is working after refactoring\`
\`revert 260220,260221 Ensure it is working after refactoring\``,
            operation: this.revertCommand.bind(this),
        };
        this._commands.set("rollout", revertCommand);
        this._commands.set("revert", revertCommand);
        this._commands.set("dry-revert", {
            description: "Parse revert message, but do not revert actually.",
            usage: `\`dry-revert SVN_REVISION [SVN_REVISIONS] REASON\`
e.g. \`dry-revert 260220 Ensure it is working after refactoring\`
\`dry-revert 260220,260221 Ensure it is working after refactoring\``,
            operation: this.dryRevertCommand.bind(this),
        });
        this._commands.set("ping", {
            description: "Responds with pong to check if WebKitBot is alive/working",
            usage: "`ping`",
            operation: this.pingCommand.bind(this),
        });
        this._commands.set("pull", {
            description: "Pulls the latest checkout of WebKit checkout for reverting queue.",
            usage: "`pull`",
            operation: this.pullCommand.bind(this),
        });

        this._commands.set("help", {
            description: "Provides help on my individual commands.",
            usage: "`help [COMMAND]`",
            operation: this.helpCommand.bind(this),
        });
        this._commands.set("status", {
            description: "Shows current reverting queue status.",
            usage: "`status`",
            operation: this.statusCommand.bind(this),
        });
        this._commands.set("hi", {
            description: "Responds with hi.",
            usage: "`hi`",
            operation: this.hiCommand.bind(this),
        });
        this._commands.set("yt?", {
            description: "Responds with yes.",
            usage: "`yt?`",
            operation: this.youThereCommand.bind(this),
        });


        this._rtm = new SlackRTMAPI.RTMClient(process.env.SLACK_TOKEN);
        this._rtm.on("message", async (event) => {
            if (event.type !== "message")
                return;

            // If message has subtype, this is not an usual message.
            if (event.subtype)
                return;

            let text = extractTextIfMentioned(event.text, this._auth.user_id);
            if (text) {
                let {command, args} = extractCommandAndArgs(text);
                let operation = this._commands.get(command);
                if (operation)
                    await operation.operation(event, command, args);
                else
                    await this.unknownCommand(event, command, args);
            }
        });
        setInterval(() => {
            this._taskQueue.postOrFailWhenExceedingLimit({
                command: "pull",
            });
        }, defaultPullPeriod);
    }

    async revertCommand(event, command, args)
    {
        let {revisions, reason} = extractRevisionsAndReason(args);

        if (!isASCII(reason)) {
            await this._web.chat.postMessage({
                channel: event.channel,
                text: `<@${event.user}> webkit-patch only accepts an ASCII string for reason: \`${escapeForSlackText(reason)}\``,
            });
            return;
        }

        dataLogLn(revisions, reason);
        if (revisions.length) {
            try {
                await this._web.chat.postMessage({
                    channel: event.channel,
                    text: `<@${event.user}> Preparing revert for ${revisions.map((revision) => `<${escapeForSlackText(`https://trac.webkit.org/r${revision}|r${revision}`)}>`).join(" ")} ...`,
                });
                let bugId = await this._taskQueue.postOrFailWhenExceedingLimit({
                    command: "revert",
                    revisions,
                    reason,
                });
                await this._web.chat.postMessage({
                    channel: event.channel,
                    text: `<@${event.user}> Created a revert patch https://webkit.org/b/${escapeForSlackText(bugId)}`,
                });
            } catch (error) {
                console.error(error);
                let stderr = error.stderr;
                console.error("STDERR ", stderr);
                if (typeof stderr === "string") {
                    {
                        let index = stderr.indexOf("Failed to apply reverse diff for revision");
                        if (index !== -1) {
                            let lines = stderr.slice(index).split("\n");
                            lines.shift();
                            let files = [];
                            for (let line of lines) {
                                try {
                                    await statAsync(path.join(process.env.webkitWorkingDirectory, line));
                                    files.push(line);
                                } catch {
                                    // THis is not a file.
                                    break;
                                }
                            }
                            if (files.length !== 0) {
                                await this._web.chat.postMessage({
                                    channel: event.channel,
                                    text: `<@${event.user}> Failed to create revert patch because of the following conflicts:
\`\`\`
${escapeForSlackText(files.join("\n"))}\`\`\``,
                                });
                                return;
                            }
                        }
                    }
                    {
                        let index = stderr.indexOf("You are not authorized to access bug");
                        if (index !== -1) {
                            let line = stderr.slice(index).split("\n")[0].trim();
                            let matched = /#(\d+)/.match(line);
                            await this._web.chat.postMessage({
                                channel: event.channel,
                                text: `<@${event.user}> Failed to create revert patch. Please ensure commit-queue@webkit.org is authorized to access ${matched ? ("bug " + escapeForSlackText(matched[1])) : "the bug"}.`
                            });
                            return;
                        }

                    }
                }
                await this._web.chat.postMessage({
                    channel: event.channel,
                    text: `<@${event.user}> Failed to create revert patch.` + (stderr ? `
\`\`\`
${escapeForSlackText(stderr)}\`\`\`` : ""),
                });
            }
            return;
        }

        await this._web.chat.postMessage({
            channel: event.channel,
            text: `<@${event.user}> Failed to parse revision and reason`,
        });
    }

    async dryRevertCommand(event, command, args)
    {
        let {revisions, reason} = extractRevisionsAndReason(args);

        if (!isASCII(reason)) {
            await this._web.chat.postMessage({
                channel: event.channel,
                text: `<@${event.user}> webkit-patch only accepts an ASCII string for reason: \`${escapeForSlackText(reason)}\``,
            });
            return;
        }

        if (!revisions.length) {
            await this._web.chat.postMessage({
                channel: event.channel,
                text: `<@${event.user}> No revision is found: reason = \`${escapeForSlackText(reason)}\``,
            });
            return;
        }

        await this._web.chat.postMessage({
            channel: event.channel,
            text: `<@${event.user}> revisions = \`${escapeForSlackText(revisions.join(","))}\`, reason = \`${escapeForSlackText(reason)}\``,
        });
    }

    async pullCommand(event, command, args)
    {
        await this._web.chat.postMessage({
            channel: event.channel,
            text: `<@${event.user}> Preparing pulling the latest WebKit checkout.`,
        });
        await this._taskQueue.postOrFailWhenExceedingLimit({
            command: "pull",
        });
        await this._web.chat.postMessage({
            channel: event.channel,
            text: `<@${event.user}> Pulled the latest checkout.`,
        });
    }

    async pingCommand(event, command, args)
    {
        await this._web.chat.postMessage({
            channel: event.channel,
            text: `<@${event.user}> pong`,
        });
    }

    async helpCommand(event, command, args)
    {
        if (args.length) {
            let commandName = args[0];
            let operation = this._commands.get(commandName);
            if (operation) {
                await this._web.chat.postMessage({
                    channel: event.channel,
                    text: `<@${event.user}> \`${escapeForSlackText(commandName)}\`: ${escapeForSlackText(operation.description)}
Usage: ${escapeForSlackText(operation.usage)}`,
                });
            } else {
                await this._web.chat.postMessage({
                    channel: event.channel,
                    text: `<@${event.user}> Unknown command \`${escapeForSlackText(commandName)}\``,
                });
            }
        } else {
            let commandNames = [];
            for (let key of this._commands.keys())
                commandNames.push("`" + key + "`");
            await this._web.chat.postMessage({
                channel: event.channel,
                text: `<@${event.user}> Available commands: ${escapeForSlackText(commandNames.join(", "))}
Type \`help COMMAND\` for help on my individual commands.`,
            });
        }
    }

    async statusCommand(event, command, args)
    {
        await this._web.chat.postMessage({
            channel: event.channel,
            text: `<@${event.user}> ${escapeForSlackText(String(this._taskQueue.length))} requests in queue.`,
        });
    }

    async hiCommand(event, command, args)
    {
        await this._web.chat.postMessage({
            channel: event.channel,
            text: `Hi <@${event.user}>!`,
        });
    }

    async youThereCommand(event, command, args)
    {
        await this._web.chat.postMessage({
            channel: event.channel,
            text: `<@${event.user}> yes`,
        });
    }

    async unknownCommand(event, command, args)
    {
        dataLogLn("Unknown command: ", command);
        await this._web.chat.postMessage({
            channel: event.channel,
            text: `<@${event.user}> Unknown command \`${escapeForSlackText(command)}\``,
        });
    }

    execInWebKitDirectorySimple(command, args)
    {
        return new Promise((resolve, reject) => {
            let task = spawn(command, args, {
                cwd: process.env.webkitWorkingDirectory,
                env: {},
                stdio: "inherit",
            });
            task.on("close", (code) => {
                if (!code)
                    resolve(code);
                else
                    reject(code);
            });
        });
    }

    async cleanUpWorkingCopy()
    {
        dataLogLn("1. Resetting");
        await this.execInWebKitDirectorySimple("git", ["reset", "--hard"]);

        dataLogLn("2. Cleaning");
        await this.execInWebKitDirectorySimple("git", ["clean", "-df"]);

        dataLogLn("3. Pulling");
        await this.execInWebKitDirectorySimple("git", ["pull"]);

        dataLogLn("4. Fetching");
        await this.execInWebKitDirectorySimple("git", ["svn", "fetch"]);
    }

    async generateRevertingPatch(revisions, reason)
    {
        dataLogLn("Reverting ", revisions, reason);
        let revisionsArgument = revisions.map((revision) => {
            let number = Number.parseInt(revision, 10);
            if (!Number.isFinite(number))
                throw new Error(`Invalid svn revision number "${String(revision)}"`);
            return number;
        }).join(" ");

        if (reason.startsWith("-"))
            throw new Error(`The revert reason may not begin with - ("${reason}")`);

        await this.cleanUpWorkingCopy();

        dataLogLn("5. Creating revert patch ", revisions, reason);
        let results;
        try {
            const webkitPatchPath = path.resolve("BotWebKit", "Tools", "Scripts", "webkit-patch");
            results = await execFileAsync(webkitPatchPath, [
                "create-revert",
                "--force-clean",
                // In principle, we should pass --non-interactive here, but it
                // turns out that create-revert doesn't need it yet.  We can't
                // pass it prophylactically because we reject unrecognized command
                // line switches.
                "--parent-command=sheriff-bot",
                revisionsArgument,
                reason,
            ], {
                cwd: process.env.webkitWorkingDirectory,
                env: {
                    CHANGE_LOG_NAME: "Commit Queue",
                    CHANGE_LOG_EMAIL_ADDRESS: "commit-queue@webkit.org",
                    webkit_bugzilla_username: process.env.webkitBugzillaUsername,
                    webkit_bugzilla_password: process.env.webkitBugzillaPassword,
                },
                timeout: defaultTimeoutForRevert,
                maxBuffer: 1024 * 1024 * 50,
            });
        } catch (error) {
            dataLogLn(error);
            let newError = new Error("Revert command failed");
            newError.stderr = error.stderr;
            throw newError;
        }
        let {stdout, stderr} = results;
        dataLogLn(stdout);
        dataLogLn(stderr);
        {
            let bugId = parseBugId(stdout);
            if (bugId !== null)
                return bugId;
        }
        {
            let bugId = parseBugId(stderr);
            if (bugId !== null)
                return bugId;
        }
        throw new Error("bug-id cannot be found");
    }

    async action(task)
    {
        dataLogLn(task);
        switch (task.command) {
        case "revert": {
            let {revisions, reason} = task;
            return this.generateRevertingPatch(revisions, reason);
        }
        case "pull":
            return this.cleanUpWorkingCopy();
        }
        throw new Error(`${task.command} is undefined action`);
    }

    static async create(webClient, auth)
    {
        let bot = new WebKitBot(webClient, auth);
        await bot._rtm.start();
        return bot;
    }

    static async main(webClient, auth)
    {
        let bot = await WebKitBot.create(webClient, auth);
        while (true) {
            let {task, resolve, reject} = await bot._taskQueue.take();
            try {
                let result = await bot.action(task);
                resolve(result);
            } catch (error) {
                reject(error);
            }
        }
    }
}
