// Copyright (C) 2012 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.server.extensions.events;

import com.google.gerrit.extensions.api.changes.NotifyHandling;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.plugincontext.PluginSetContext;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.transport.ReceiveCommand;

@Singleton
public class GitReferenceUpdated {
  public static final GitReferenceUpdated DISABLED =
      new GitReferenceUpdated() {
        @Override
        public void fire(
            Project.NameKey project,
            RefUpdate refUpdate,
            ReceiveCommand.Type type,
            AccountState updater) {}

        @Override
        public void fire(Project.NameKey project, RefUpdate refUpdate, AccountState updater) {}

        @Override
        public void fire(
            Project.NameKey project,
            String ref,
            ObjectId oldObjectId,
            ObjectId newObjectId,
            AccountState updater) {}

        @Override
        public void fire(Project.NameKey project, ReceiveCommand cmd, AccountState updater) {}

        @Override
        public void fire(
            Project.NameKey project, BatchRefUpdate batchRefUpdate, AccountState updater) {}
      };

  private final PluginSetContext<GitReferenceUpdatedListener> listeners;
  private final EventUtil util;

  @Inject
  GitReferenceUpdated(PluginSetContext<GitReferenceUpdatedListener> listeners, EventUtil util) {
    this.listeners = listeners;
    this.util = util;
  }

  private GitReferenceUpdated() {
    this.listeners = null;
    this.util = null;
  }

  public void fire(
      Project.NameKey project,
      RefUpdate refUpdate,
      ReceiveCommand.Type type,
      AccountState updater) {
    fire(
        project,
        refUpdate.getName(),
        refUpdate.getOldObjectId(),
        refUpdate.getNewObjectId(),
        type,
        util.accountInfo(updater));
  }

  public void fire(Project.NameKey project, RefUpdate refUpdate, AccountState updater) {
    fire(
        project,
        refUpdate.getName(),
        refUpdate.getOldObjectId(),
        refUpdate.getNewObjectId(),
        ReceiveCommand.Type.UPDATE,
        util.accountInfo(updater));
  }

  public void fire(
      Project.NameKey project,
      String ref,
      ObjectId oldObjectId,
      ObjectId newObjectId,
      AccountState updater) {
    fire(
        project,
        ref,
        oldObjectId,
        newObjectId,
        ReceiveCommand.Type.UPDATE,
        util.accountInfo(updater));
  }

  public void fire(Project.NameKey project, ReceiveCommand cmd, AccountState updater) {
    fire(
        project,
        cmd.getRefName(),
        cmd.getOldId(),
        cmd.getNewId(),
        cmd.getType(),
        util.accountInfo(updater));
  }

  public void fire(Project.NameKey project, BatchRefUpdate batchRefUpdate, AccountState updater) {
    if (listeners.isEmpty()) {
      return;
    }
    for (ReceiveCommand cmd : batchRefUpdate.getCommands()) {
      if (cmd.getResult() == ReceiveCommand.Result.OK) {
        fire(
            project,
            cmd.getRefName(),
            cmd.getOldId(),
            cmd.getNewId(),
            cmd.getType(),
            util.accountInfo(updater));
      }
    }
  }

  private void fire(
      Project.NameKey project,
      String ref,
      ObjectId oldObjectId,
      ObjectId newObjectId,
      ReceiveCommand.Type type,
      AccountInfo updater) {
    if (listeners.isEmpty()) {
      return;
    }
    ObjectId o = oldObjectId != null ? oldObjectId : ObjectId.zeroId();
    ObjectId n = newObjectId != null ? newObjectId : ObjectId.zeroId();
    Event event = new Event(project, ref, o.name(), n.name(), type, updater);
    listeners.runEach(l -> l.onGitReferenceUpdated(event));
  }

  public static class Event implements GitReferenceUpdatedListener.Event {
    private final String projectName;
    private final String ref;
    private final String oldObjectId;
    private final String newObjectId;
    private final ReceiveCommand.Type type;
    private final AccountInfo updater;

    Event(
        Project.NameKey project,
        String ref,
        String oldObjectId,
        String newObjectId,
        ReceiveCommand.Type type,
        AccountInfo updater) {
      this.projectName = project.get();
      this.ref = ref;
      this.oldObjectId = oldObjectId;
      this.newObjectId = newObjectId;
      this.type = type;
      this.updater = updater;
    }

    @Override
    public String getProjectName() {
      return projectName;
    }

    @Override
    public String getRefName() {
      return ref;
    }

    @Override
    public String getOldObjectId() {
      return oldObjectId;
    }

    @Override
    public String getNewObjectId() {
      return newObjectId;
    }

    @Override
    public boolean isCreate() {
      return type == ReceiveCommand.Type.CREATE;
    }

    @Override
    public boolean isDelete() {
      return type == ReceiveCommand.Type.DELETE;
    }

    @Override
    public boolean isNonFastForward() {
      return type == ReceiveCommand.Type.UPDATE_NONFASTFORWARD;
    }

    @Override
    public AccountInfo getUpdater() {
      return updater;
    }

    @Override
    public String toString() {
      return String.format(
          "%s[%s,%s: %s -> %s]",
          getClass().getSimpleName(), projectName, ref, oldObjectId, newObjectId);
    }

    @Override
    public NotifyHandling getNotify() {
      return NotifyHandling.ALL;
    }
  }
}
