// 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.reviewers;

import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.gerrit.common.EventListener;
import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountByEmailCache;
import com.google.gerrit.server.account.AccountResolver;
import com.google.gerrit.server.account.GroupMembers;
import com.google.gerrit.server.events.DraftPublishedEvent;
import com.google.gerrit.server.events.Event;
import com.google.gerrit.server.events.PatchSetCreatedEvent;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.WorkQueue;
import com.google.gerrit.server.group.GroupsCollection;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.query.Predicate;
import com.google.gerrit.server.query.QueryParseException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.ChangeQueryBuilder;
import com.google.gerrit.server.util.RequestContext;
import com.google.gerrit.server.util.ThreadLocalRequestContext;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.ProvisionException;

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

import java.io.IOException;
import java.util.List;
import java.util.Set;

class ChangeEventListener implements EventListener {
  private static final Logger log = LoggerFactory
      .getLogger(ChangeEventListener.class);

  private final AccountResolver accountResolver;
  private final AccountByEmailCache byEmailCache;
  private final Provider<GroupsCollection> groupsCollection;
  private final GroupMembers.Factory groupMembersFactory;
  private final DefaultReviewers.Factory reviewersFactory;
  private final GitRepositoryManager repoManager;
  private final WorkQueue workQueue;
  private final IdentifiedUser.GenericFactory identifiedUserFactory;
  private final ThreadLocalRequestContext tl;
  private final SchemaFactory<ReviewDb> schemaFactory;
  private final ChangeData.Factory changeDataFactory;
  private final ReviewersConfig.Factory configFactory;
  private final Provider<CurrentUser> user;
  private final ChangeQueryBuilder queryBuilder;
  private ReviewDb db;

  @Inject
  ChangeEventListener(
      final AccountResolver accountResolver,
      final AccountByEmailCache byEmailCache,
      final Provider<GroupsCollection> groupsCollection,
      final GroupMembers.Factory groupMembersFactory,
      final DefaultReviewers.Factory reviewersFactory,
      final GitRepositoryManager repoManager,
      final WorkQueue workQueue,
      final IdentifiedUser.GenericFactory identifiedUserFactory,
      final ThreadLocalRequestContext tl,
      final SchemaFactory<ReviewDb> schemaFactory,
      final ChangeData.Factory changeDataFactory,
      final ReviewersConfig.Factory configFactory,
      final Provider<CurrentUser> user,
      final ChangeQueryBuilder queryBuilder) {
    this.accountResolver = accountResolver;
    this.byEmailCache = byEmailCache;
    this.groupsCollection = groupsCollection;
    this.groupMembersFactory = groupMembersFactory;
    this.reviewersFactory = reviewersFactory;
    this.repoManager = repoManager;
    this.workQueue = workQueue;
    this.identifiedUserFactory = identifiedUserFactory;
    this.tl = tl;
    this.schemaFactory = schemaFactory;
    this.changeDataFactory = changeDataFactory;
    this.configFactory = configFactory;
    this.user = user;
    this.queryBuilder = queryBuilder;
  }

  @Override
  public void onEvent(Event event) {
    if (event instanceof PatchSetCreatedEvent) {
      PatchSetCreatedEvent e = (PatchSetCreatedEvent) event;
      onEvent(new Project.NameKey(e.change.project),
          Integer.parseInt(e.change.number),
          Integer.parseInt(e.patchSet.number), e.uploader.email);
    } else if (event instanceof DraftPublishedEvent) {
      DraftPublishedEvent e = (DraftPublishedEvent) event;
      onEvent(new Project.NameKey(e.change.project),
          Integer.parseInt(e.change.number),
          Integer.parseInt(e.patchSet.number), e.uploader.email);
    }
  }

  private void onEvent(Project.NameKey projectName, int changeNumber,
      int patchSetNumber, String email) {

    // TODO(davido): we have to cache per project configuration
    ReviewersConfig config = configFactory.create(projectName);
    List<ReviewerFilterSection> sections = config.getReviewerFilterSections();

    if (sections.isEmpty()) {
      return;
    }

    try (Repository git = repoManager.openRepository(projectName);
        RevWalk rw = new RevWalk(git);
        ReviewDb reviewDb = schemaFactory.open()) {
      Change.Id changeId = new Change.Id(changeNumber);
      PatchSet.Id psId =
          new PatchSet.Id(changeId, patchSetNumber);
      PatchSet ps = reviewDb.patchSets().get(psId);
      if (ps == null) {
        log.warn("Patch set " + psId.get() + " not found.");
        return;
      }

      final Change change = reviewDb.changes().get(psId.getParentKey());
      if (change == null) {
        log.warn("Change " + changeId.get() + " not found.");
        return;
      }

      Set<String> reviewers = findReviewers(sections, reviewDb, change);
      if (reviewers.isEmpty()) {
        return;
      }

      final Runnable task =
          reviewersFactory.create(change,
              toAccounts(reviewers, projectName, email));

      workQueue.getDefaultQueue().submit(new Runnable() {
        @Override
        public void run() {
          RequestContext old = tl.setContext(new RequestContext() {

            @Override
            public CurrentUser getUser() {
              return identifiedUserFactory.create(change.getOwner());
            }

            @Override
            public Provider<ReviewDb> getReviewDbProvider() {
              return new Provider<ReviewDb>() {
                @Override
                public ReviewDb get() {
                  if (db == null) {
                    try {
                      db = schemaFactory.open();
                    } catch (OrmException e) {
                      throw new ProvisionException("Cannot open ReviewDb", e);
                    }
                  }
                  return db;
                }
              };
            }
          });
          try {
            task.run();
          } finally {
            tl.setContext(old);
            if (db != null) {
              db.close();
              db = null;
            }
          }
        }
      });
    } catch (OrmException | IOException | QueryParseException x) {
      log.error(x.getMessage(), x);
    }
  }

  private Set<String> findReviewers(
      List<ReviewerFilterSection> sections, final ReviewDb reviewDb,
      final Change change) throws OrmException, QueryParseException {
    ImmutableSet.Builder<String> reviewers = ImmutableSet.builder();
    List<ReviewerFilterSection> found = findReviewerSections(sections, reviewDb, change);
    for (ReviewerFilterSection s : found) {
      reviewers.addAll(s.getReviewers());
    }
    return reviewers.build();
  }

  private List<ReviewerFilterSection> findReviewerSections(
      List<ReviewerFilterSection> sections, final ReviewDb reviewDb,
      final Change change) throws OrmException, QueryParseException {
    ImmutableList.Builder<ReviewerFilterSection> found = ImmutableList.builder();
    ChangeData changeData = changeDataFactory.create(reviewDb, change);
    for (ReviewerFilterSection s : sections) {
      if (Strings.isNullOrEmpty(s.getFilter())
          || s.getFilter().equals("*")) {
        found.add(s);
      } else if (filterMatch(s.getFilter(), changeData)) {
        found.add(s);
      }
    }
    return found.build();
  }

  boolean filterMatch(String filter, ChangeData changeData)
      throws OrmException, QueryParseException {
    Preconditions.checkNotNull(filter);
    ChangeQueryBuilder qb = queryBuilder.asUser(user.get());
    Predicate<ChangeData> filterPredicate = qb.parse(filter);
    // TODO(davido): check that the potential review can see this change
    // by adding AND is_visible() predicate? Or is it OK to assume
    // that reviewers always can see it?
    return filterPredicate.match(changeData);
  }

  private Set<Account> toAccounts(Set<String> in, Project.NameKey p,
      String uploaderEMail) {
    Set<Account> reviewers = Sets.newHashSetWithExpectedSize(in.size());
    GroupMembers groupMembers = null;
    for (String r : in) {
      try {
        Account account = accountResolver.find(r);
        if (account != null) {
          reviewers.add(account);
          continue;
        }
      } catch (OrmException e) {
        // If the account doesn't exist, find() will return null.  We only
        // get here if something went wrong accessing the database
        log.error("Failed to resolve account " + r, e);
        continue;
      }
      if (groupMembers == null) {
        groupMembers =
            groupMembersFactory.create(identifiedUserFactory.create(Iterables
                .getOnlyElement(byEmailCache.get(uploaderEMail))));
      }
      try {
        reviewers.addAll(groupMembers.listAccounts(
            groupsCollection.get().parse(r).getGroupUUID(), p));
      } catch (UnprocessableEntityException | NoSuchGroupException e) {
        log.warn(String.format(
            "Reviewer %s is neither an account nor a group", r));
      } catch (NoSuchProjectException e) {
        log.warn(String.format(
            "Failed to list accounts for group %s and project %s", r, p));
      } catch (IOException | OrmException e) {
        log.warn(String.format("Failed to list accounts for group %s", r), e);
      }
    }
    return reviewers;
  }
}
