// Copyright (C) 2010 The Android Open Source Project
//
// 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.google.gerrit.common;

import com.google.gerrit.common.data.ApprovalType;
import com.google.gerrit.common.data.ApprovalTypes;
import com.google.gerrit.reviewdb.Account;
import com.google.gerrit.reviewdb.ApprovalCategory;
import com.google.gerrit.reviewdb.ApprovalCategoryValue;
import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.reviewdb.PatchSet;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.WorkQueue;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.inject.internal.Nullable;

import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Repository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

/**
 * This class implements hooks for certain gerrit events.
 */
@Singleton
public class ChangeHookRunner {
    /** A logger for this class. */
    private static final Logger log = LoggerFactory.getLogger(ChangeHookRunner.class);

    public static abstract class ChangeEvent {
    }

    public static class ApprovalAttribute {
        public String type;
        public String description;
        public String value;
    }

    public static class AuthorAttribute {
        public String name;
        public String email;
    }

    public static class ChangeAttribute {
        public String project;
        public String branch;
        public String id;
        public String number;
        public String subject;
        public AuthorAttribute owner;
        public String url;
    }

    public static class PatchSetAttribute {
        public String number;
        public String revision;
        public String ref;
    }

    public static class CommentAddedEvent extends ChangeEvent {
        public final String type = "comment-added";
        public ChangeAttribute change;
        public PatchSetAttribute patchSet;
        public AuthorAttribute author;
        public ApprovalAttribute[] approvals;
        public String comment;
    }

    public static class ChangeMergedEvent extends ChangeEvent {
        public final String type = "change-merged";
        public ChangeAttribute change;
        public PatchSetAttribute patchSet;
        public AuthorAttribute submitter;
    }

    public static class ChangeAbandonedEvent extends ChangeEvent {
        public final String type = "change-abandoned";
        public ChangeAttribute change;
        public PatchSetAttribute patchSet;
        public AuthorAttribute abandoner;
        public String reason;
    }

    public static class PatchSetCreatedEvent extends ChangeEvent {
        public final String type = "patchset-created";
        public ChangeAttribute change;
        public PatchSetAttribute patchSet;
    }

    private static class ChangeListenerHolder {
        final ChangeListener listener;
        final IdentifiedUser user;

        ChangeListenerHolder(ChangeListener l, IdentifiedUser u) {
            listener = l;
            user = u;
        }
    }

    /** Listeners to receive changes as they happen. */
    private final Map<ChangeListener, ChangeListenerHolder> listeners =
      new ConcurrentHashMap<ChangeListener, ChangeListenerHolder>();

    /** Filename of the new patchset hook. */
    private final File patchsetCreatedHook;

    /** Filename of the new comments hook. */
    private final File commentAddedHook;

    /** Filename of the change merged hook. */
    private final File changeMergedHook;

    /** Filename of the change abandoned hook. */
    private final File changeAbandonedHook;

    /** Repository Manager. */
    private final GitRepositoryManager repoManager;

    /** Queue of hooks that need to run. */
    private final WorkQueue.Executor hookQueue;

    private final ProjectCache projectCache;

    private final AccountCache accountCache;

    private final ApprovalTypes approvalTypes;

    private final Provider<String> urlProvider;


    /**
     * Create a new ChangeHookRunner.
     *
     * @param queue Queue to use when processing hooks.
     * @param repoManager The repository manager.
     * @param config Config file to use.
     * @param sitePath The sitepath of this gerrit install.
     * @param projectCache the project cache instance for the server.
     */
    @Inject
    public ChangeHookRunner(final WorkQueue queue,
      final GitRepositoryManager repoManager,
      @GerritServerConfig final Config config, final SitePaths sitePath,
      final ProjectCache projectCache,
      final AccountCache accountCache,
      final ApprovalTypes approvalTypes,
      @CanonicalWebUrl @Nullable final Provider<String> cwu) {
        this.repoManager = repoManager;
        this.hookQueue = queue.createQueue(1, "hook");
        this.projectCache = projectCache;
        this.accountCache = accountCache;
        this.approvalTypes = approvalTypes;
        this.urlProvider = cwu;

        final File hooksPath = sitePath.resolve(getValue(config, "hooks", "path", sitePath.hooks_dir.getAbsolutePath()));

        patchsetCreatedHook = sitePath.resolve(new File(hooksPath, getValue(config, "hooks", "patchsetCreatedHook", "patchset-created")).getPath());
        commentAddedHook = sitePath.resolve(new File(hooksPath, getValue(config, "hooks", "commentAddedHook", "comment-added")).getPath());
        changeMergedHook = sitePath.resolve(new File(hooksPath, getValue(config, "hooks", "changeMergedHook", "change-merged")).getPath());
        changeAbandonedHook = sitePath.resolve(new File(hooksPath, getValue(config, "hooks", "changeAbandonedHook", "change-abandoned")).getPath());
    }

    public void addChangeListener(ChangeListener listener, IdentifiedUser user) {
        listeners.put(listener, new ChangeListenerHolder(listener, user));
    }

    public void removeChangeListener(ChangeListener listener) {
        listeners.remove(listener);
    }

    /**
     * Helper Method for getting values from the config.
     *
     * @param config Config file to get value from.
     * @param section Section to look in.
     * @param setting Setting to get.
     * @param fallback Fallback value.
     * @return Setting value if found, else fallback.
     */
    private String getValue(final Config config, final String section, final String setting, final String fallback) {
        final String result = config.getString(section, null, setting);
        return (result == null) ? fallback : result;
    }

    /**
     * Get the Repository for the given change, or null on error.
     *
     * @param change Change to get repo for,
     * @return Repository or null.
     */
    private Repository getRepo(final Change change) {
        try {
            return repoManager.openRepository(change.getProject().get());
        } catch (Exception ex) {
            return null;
        }
    }

    /**
     * Fire the Patchset Created Hook.
     *
     * @param change The change itself.
     * @param patchSet The Patchset that was created.
     */
    public void doPatchsetCreatedHook(final Change change, final PatchSet patchSet) {
        final PatchSetCreatedEvent event = new PatchSetCreatedEvent();

        event.change = getChangeAttribute(change);
        event.patchSet = getPatchSetAttribute(patchSet);
        fireEvent(change, event);

        final List<String> args = new ArrayList<String>();
        args.add(patchsetCreatedHook.getAbsolutePath());

        args.add("--change");
        args.add(event.change.id);
        args.add("--change-url");
        args.add(event.change.url);
        args.add("--project");
        args.add(event.change.project);
        args.add("--branch");
        args.add(event.change.branch);
        args.add("--commit");
        args.add(event.patchSet.revision);
        args.add("--patchset");
        args.add(event.patchSet.number);

        runHook(getRepo(change), args);
    }

    /**
     * Fire the Comment Added Hook.
     *
     * @param change The change itself.
     * @param patchSet The patchset this comment is related to.
     * @param account The gerrit user who commited the change.
     * @param comment The comment given.
     * @param approvals Map of Approval Categories and Scores
     */
    public void doCommentAddedHook(final Change change, final Account account, final PatchSet patchSet, final String comment, final Map<ApprovalCategory.Id, ApprovalCategoryValue.Id> approvals) {
        final CommentAddedEvent event = new CommentAddedEvent();

        event.change = getChangeAttribute(change);
        event.author =  getAccountAttribute(account);
        event.patchSet = getPatchSetAttribute(patchSet);
        event.comment = comment;

        if (approvals.size() > 0) {
            event.approvals = new ApprovalAttribute[approvals.size()];
            int i = 0;
            for (Map.Entry<ApprovalCategory.Id, ApprovalCategoryValue.Id> approval : approvals.entrySet()) {
                event.approvals[i++] = getApprovalAttribute(approval);
            }
        }

        fireEvent(change, event);

        final List<String> args = new ArrayList<String>();
        args.add(commentAddedHook.getAbsolutePath());

        args.add("--change");
        args.add(event.change.id);
        args.add("--change-url");
        args.add(event.change.url);
        args.add("--project");
        args.add(event.change.project);
        args.add("--branch");
        args.add(event.change.branch);
        args.add("--author");
        args.add(getDisplayName(account));
        args.add("--commit");
        args.add(event.patchSet.revision);
        args.add("--comment");
        args.add(comment == null ? "" : comment);
        for (Map.Entry<ApprovalCategory.Id, ApprovalCategoryValue.Id> approval : approvals.entrySet()) {
            args.add("--" + approval.getKey().get());
            args.add(Short.toString(approval.getValue().get()));
        }

        runHook(getRepo(change), args);
    }

    /**
     * Fire the Change Merged Hook.
     *
     * @param change The change itself.
     * @param account The gerrit user who commited the change.
     * @param patchSet The patchset that was merged.
     */
    public void doChangeMergedHook(final Change change, final Account account, final PatchSet patchSet) {
        final ChangeMergedEvent event = new ChangeMergedEvent();

        event.change = getChangeAttribute(change);
        event.submitter =  getAccountAttribute(account);
        event.patchSet = getPatchSetAttribute(patchSet);
        fireEvent(change, event);

        final List<String> args = new ArrayList<String>();
        args.add(changeMergedHook.getAbsolutePath());

        args.add("--change");
        args.add(event.change.id);
        args.add("--change-url");
        args.add(event.change.url);
        args.add("--project");
        args.add(event.change.project);
        args.add("--branch");
        args.add(event.change.branch);
        args.add("--submitter");
        args.add(getDisplayName(account));
        args.add("--commit");
        args.add(event.patchSet.revision);

        runHook(getRepo(change), args);
    }

    /**
     * Fire the Change Abandoned Hook.
     *
     * @param change The change itself.
     * @param account The gerrit user who abandoned the change.
     * @param reason Reason for abandoning the change.
     */
    public void doChangeAbandonedHook(final Change change, final Account account, final String reason) {
        final ChangeAbandonedEvent event = new ChangeAbandonedEvent();

        event.change = getChangeAttribute(change);
        event.abandoner = getAccountAttribute(account);
        event.reason = reason;
        fireEvent(change, event);

        final List<String> args = new ArrayList<String>();
        args.add(changeAbandonedHook.getAbsolutePath());

        args.add("--change");
        args.add(event.change.id);
        args.add("--change-url");
        args.add(event.change.url);
        args.add("--project");
        args.add(event.change.project);
        args.add("--branch");
        args.add(event.change.branch);
        args.add("--abandoner");
        args.add(getDisplayName(account));
        args.add("--reason");
        args.add(reason == null ? "" : reason);

        runHook(getRepo(change), args);
    }

    private void fireEvent(final Change change, final ChangeEvent event) {
      for (ChangeListenerHolder holder : listeners.values()) {
          if (isVisibleTo(change, holder.user)) {
              holder.listener.onChangeEvent(event);
          }
      }
    }

    private boolean isVisibleTo(Change change, IdentifiedUser user) {
        final ProjectState pe = projectCache.get(change.getProject());
        if (pe == null) {
          return false;
        }
        final ProjectControl pc = pe.controlFor(user);
        return pc.controlFor(change).isVisible();
    }

    /** Get a link to the change; null if the server doesn't know its own address. */
    private String getChangeUrl(final Change change) {
        if (change != null && getGerritUrl() != null) {
            final StringBuilder r = new StringBuilder();
            r.append(getGerritUrl());
            r.append(change.getChangeId());
            return r.toString();
        }
        return null;
    }

    private String getGerritUrl() {
        return urlProvider.get();
    }


    /**
     * Create an ApprovalAttribute for the given approval suitable for serialization to JSON.
     * @param approval
     * @return object suitable for serialization to JSON
     */
    private ApprovalAttribute getApprovalAttribute(
            Entry<ApprovalCategory.Id, ApprovalCategoryValue.Id> approval) {
        ApprovalAttribute a = new ApprovalAttribute();
        a.type = approval.getKey().get();
        final ApprovalType at = approvalTypes.getApprovalType(approval.getKey());
        a.description = at.getCategory().getName();
        a.value = Short.toString(approval.getValue().get());
        return a;
    }

    /**
     * Create an AuthorAttribute for the given account suitable for serialization to JSON.
     *
     * @param account
     * @return object suitable for serialization to JSON
     */
    private AuthorAttribute getAccountAttribute(final Account account) {
        AuthorAttribute author = new AuthorAttribute();
        author.name = account.getFullName();
        author.email = account.getPreferredEmail();
        return author;
    }

    /**
     * Create a ChangeAttribute for the given change suitable for serialization to JSON.
     *
     * @param change
     * @return object suitable for serialization to JSON
     */
    private ChangeAttribute getChangeAttribute(final Change change) {
        ChangeAttribute a = new ChangeAttribute();
        a.project = change.getProject().get();
        a.branch = change.getDest().getShortName();
        a.id = change.getKey().get();
        a.number = change.getId().toString();
        a.subject = change.getSubject();
        final AccountState owner = accountCache.get(change.getOwner());
        a.owner = getAccountAttribute(owner.getAccount());
        a.url = getChangeUrl(change);
        return a;
    }

    /**
     * Create an PatchSetAttribute for the given patchset suitable for serialization to JSON.
     *
     * @param patchSet
     * @return object suitable for serialization to JSON
     */
    private PatchSetAttribute getPatchSetAttribute(final PatchSet patchSet) {
        PatchSetAttribute p = new PatchSetAttribute();
        p.revision = patchSet.getRevision().get();
        p.number = Integer.toString(patchSet.getPatchSetId());
        p.ref = patchSet.getRefName();
        return p;
    }

    /**
     * Get the display name for the given account.
     *
     * @param account Account to get name for.
     * @return Name for this account.
     */
    private String getDisplayName(final Account account) {
        if (account != null) {
            String result = (account.getFullName() == null) ? "Anonymous Coward" : account.getFullName();
            if (account.getPreferredEmail() != null) {
                result += " (" + account.getPreferredEmail() + ")";
            }
            return result;
        }

        return "Anonymous Coward";
    }

    /**
     * Run a hook.
     *
     * @param repo Repo to run the hook for.
     * @param args Arguments to use to run the hook.
     */
    private synchronized void runHook(final Repository repo, final List<String> args) {
        if (repo == null) {
            log.error("No repo found for hook.");
            return;
        }

        hookQueue.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    if (new File(args.get(0)).exists()) {
                        final ProcessBuilder pb = new ProcessBuilder(args);
                        pb.redirectErrorStream(true);
                        pb.directory(repo.getDirectory());
                        final Map<String, String> env = pb.environment();
                        env.put("GIT_DIR", repo.getDirectory().getAbsolutePath());

                        Process ps = pb.start();
                        ps.getOutputStream().close();

                        BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));
                        try {
                            String line;
                            while ((line = br.readLine()) != null) {
                                log.info("hook output: " + line);
                            }
                        } finally {
                            try {
                                br.close();
                            } catch (IOException e2) {
                            }

                            ps.waitFor();
                        }
                    }
                } catch (Throwable e) {
                    log.error("Unexpected error during hook execution", e);
                } finally {
                    repo.close();
                }
            }
        });
    }
}
