// Copyright (C) 2014 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.gitiles;

import com.google.common.annotations.VisibleForTesting;
import java.io.IOException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.StopWalkException;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.revwalk.filter.RevFilter;

/** Filter which only includes commits matching a person identity. */
public abstract class IdentRevFilter extends RevFilter {
  public static IdentRevFilter author(String author) {
    return new Author(author);
  }

  public static IdentRevFilter committer(String committer) {
    return new Committer(committer);
  }

  private final String pattern;

  protected IdentRevFilter(String pattern) {
    this.pattern = pattern;
  }

  @Override
  public boolean include(RevWalk walker, RevCommit commit)
      throws StopWalkException, MissingObjectException, IncorrectObjectTypeException, IOException {
    return matchesPerson(getIdent(walker, commit));
  }

  @Override
  public RevFilter clone() {
    return this;
  }

  /**
   * Whether the given person matches the author filter.
   *
   * @return whether the given person matches the author filter.
   */
  @VisibleForTesting
  boolean matchesPerson(PersonIdent person) {
    // Equivalent to --fixed-strings, to avoid pathological performance of Java
    // regex matching.
    // TODO(kalman): Find/use a port of re2.
    return person.getName().contains(pattern) || person.getEmailAddress().contains(pattern);
  }

  protected abstract PersonIdent getIdent(RevWalk walk, RevCommit commit)
      throws MissingObjectException, IOException;

  private static class Author extends IdentRevFilter {
    private Author(String author) {
      super(author);
    }

    @Override
    protected PersonIdent getIdent(RevWalk walk, RevCommit commit)
        throws MissingObjectException, IOException {
      walk.parseBody(commit);
      return commit.getAuthorIdent();
    }
  }

  private static class Committer extends IdentRevFilter {
    private Committer(String committer) {
      super(committer);
    }

    @Override
    protected PersonIdent getIdent(RevWalk walk, RevCommit commit)
        throws MissingObjectException, IOException {
      walk.parseBody(commit);
      return commit.getCommitterIdent();
    }
  }
}
