// Copyright (C) 2013 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.googlesource.gerrit.plugins.hooks.workflow;

import java.io.IOException;

import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gerrit.common.ChangeListener;
import com.google.gerrit.reviewdb.client.Project.NameKey;
import com.google.gerrit.server.events.ChangeAbandonedEvent;
import com.google.gerrit.server.events.ChangeEvent;
import com.google.gerrit.server.events.ChangeMergedEvent;
import com.google.gerrit.server.events.ChangeRestoredEvent;
import com.google.gerrit.server.events.CommentAddedEvent;
import com.google.gerrit.server.events.PatchSetCreatedEvent;
import com.google.gerrit.server.events.RefUpdatedEvent;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;

public class GerritHookFilter implements ChangeListener {
  private static final Logger log = LoggerFactory.getLogger(GerritHookFilter.class);

  @Inject
  private GitRepositoryManager repoManager;

  public String getComment(String projectName, String commitId)
      throws IOException {

    final Repository repo =
        repoManager.openRepository(new NameKey(projectName));
    try {
      RevWalk revWalk = new RevWalk(repo);
      RevCommit commit = revWalk.parseCommit(ObjectId.fromString(commitId));

      return commit.getFullMessage();
    } finally {
      repo.close();
    }
  }

  public void doFilter(PatchSetCreatedEvent hook) throws IOException,
      OrmException {
  }

  public void doFilter(CommentAddedEvent hook) throws IOException {
  }

  public void doFilter(ChangeMergedEvent hook) throws IOException {
  }

  public void doFilter(ChangeAbandonedEvent changeAbandonedHook)
      throws IOException {
  }

  public void doFilter(ChangeRestoredEvent changeRestoredHook)
      throws IOException {
  }

  public void doFilter(RefUpdatedEvent refUpdatedHook) throws IOException {
  }

  @Override
  public void onChangeEvent(ChangeEvent event) {
    try {
      if (event instanceof PatchSetCreatedEvent) {
        doFilter((PatchSetCreatedEvent) event);
      } else if (event instanceof CommentAddedEvent) {
        doFilter((CommentAddedEvent) event);
      } else if (event instanceof ChangeMergedEvent) {
        doFilter((ChangeMergedEvent) event);
      } else if (event instanceof ChangeAbandonedEvent) {
        doFilter((ChangeAbandonedEvent) event);
      } else if (event instanceof ChangeRestoredEvent) {
        doFilter((ChangeRestoredEvent) event);
      } else if (event instanceof RefUpdatedEvent) {
        doFilter((RefUpdatedEvent) event);
      } else {
        log.debug("Event " + event + " not recognised and ignored");
      }
    } catch (Throwable e) {
      log.error("Event " + event + " processing failed", e);
    }
  }

  public String getUrl(PatchSetCreatedEvent hook) {
    return null;
  }
}
