/*
 * Copyright (c) 2017 Cisco and/or its affiliates.
 *
 * 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 io.fd.maintainer.plugin.events;

import static io.fd.maintainer.plugin.service.PatchsetReviewInfo.ReviewState.ALL_COMPONENTS_REVIEWED;
import static io.fd.maintainer.plugin.service.PatchsetReviewInfo.ReviewState.COMMITTER_ATTENTION_NEEDED;
import static java.lang.String.format;

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.PatchSetApproval;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.change.ChangesCollection;
import com.google.gerrit.server.data.AccountAttribute;
import com.google.gerrit.server.data.ApprovalAttribute;
import com.google.gerrit.server.events.CommentAddedEvent;
import com.google.gerrit.server.events.Event;
import com.google.gerrit.server.patch.PatchList;
import com.google.gerrit.server.patch.PatchListCache;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
import io.fd.maintainer.plugin.service.MaintainersProvider;
import io.fd.maintainer.plugin.service.PatchsetReviewInfo;
import io.fd.maintainer.plugin.service.SettingsProvider;
import io.fd.maintainer.plugin.service.dto.PluginBranchSpecificSettings;
import io.fd.maintainer.plugin.service.push.ApprovalPusher;
import io.fd.maintainer.plugin.service.push.SubmitPusher;
import io.fd.maintainer.plugin.util.MaintainersIndex;
import io.fd.maintainer.plugin.util.PatchListProcessing;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class OnPatchsetVerifiedListener extends SelfDescribingEventListener implements PatchListProcessing {

    private static final Logger LOG = LoggerFactory.getLogger(OnPatchsetVerifiedListener.class);

    @Inject
    private SchemaFactory<ReviewDb> schemaFactory;

    @Inject
    private MaintainersProvider maintainersProvider;

    @Inject
    private PatchListCache patchListCache;

    @Inject
    private ChangesCollection changes;

    @Inject
    private SettingsProvider settingsProvider;

    @Inject
    private ApprovalPusher approvalPusher;

    @Inject
    private SubmitPusher submitPusher;

    private static String formatUser(final AccountAttribute author) {
        return format("%s(%s)<%s>", author.name, author.username, author.email);
    }

    @Override
    protected void consumeDescribedEvent(final Event event) {
        CommentAddedEvent commentAddedEvent = CommentAddedEvent.class.cast(event);

        final Project.NameKey projectKey = new Project.NameKey(commentAddedEvent.change.get().project);
        final PluginBranchSpecificSettings settings =
                settingsProvider.getBranchSpecificSettings(commentAddedEvent.change.get().branch, projectKey);

        if (!settings.isAllowMaintainersSubmit()) {
            LOG.warn("Maintainers submit is turned off");
            return;
        }

        final Optional<ApprovalAttribute> patchSetVerification = getPatchListVerifications(commentAddedEvent);

        // patchset has been +1
        if (patchSetVerification.isPresent()) {
            LOG.info("User {} just verified change {}", formatUser(commentAddedEvent.author.get()),
                    commentAddedEvent.changeKey.get());

            try (final ReviewDb reviewDb = schemaFactory.open()) {
                final int changeNumber = commentAddedEvent.change.get().number;
                final Change.Id changeId = new Change.Id(changeNumber);
                final Change change = reviewDb.changes().get(changeId);

                final PatchSet currentPatchset = reviewDb.patchSets().get(change.currentPatchSetId());
                final PatchSet.Id currentPatchsetId = currentPatchset.getId();

                final int currentPatchsetNr = currentPatchset.getPatchSetId();
                final int processedPatchsetNr = commentAddedEvent.patchSet.get().number;

                // to filter out reviews on older patchsets
                if (currentPatchsetNr != processedPatchsetNr) {
                    LOG.warn("Event for older patchset {}, most current {}, ignoring", processedPatchsetNr,
                            currentPatchsetNr);
                } else {
                    final List<PatchSetApproval> currentPatchsetVerifications = getPatchListCurrentVerifications(
                            reviewDb.patchSetApprovals().byChange(changeId).toList(),
                            currentPatchsetId);

                    if (currentPatchsetVerifications.isEmpty()) {
                        LOG.warn("No verifications found for patchset {}", currentPatchset.getId());
                    } else {
                        LOG.info("Building maintainers index for patchset {}", currentPatchset.getId());
                        final MaintainersIndex maintainersIndex =
                                new MaintainersIndex(maintainersProvider
                                        .getMaintainersInfo(commentAddedEvent.getBranchNameKey().get(),
                                                changeNumber, projectKey));

                        LOG.info("Getting current patch list for patchset {}", currentPatchset.getId());
                        final PatchList patchList = getPatchList(patchListCache, change, currentPatchset);

                        LOG.info("Getting current reviewers for patchset {}", currentPatchset.getId());
                        final HashSet<Account> currentVerificators =
                                new HashSet<>(reviewDb.accounts().get(currentPatchsetVerifications
                                        .stream()
                                        .map(PatchSetApproval::getAccountId)
                                        .collect(Collectors.toSet())).toList());

                        LOG.info("Getting patch review info for patchset {}", currentPatchset.getId());
                        // Note that you only need one MAINTAINER per component.
                        // Also note a single reviewer may be a MAINTAINER for multiple components
                        final PatchsetReviewInfo patchsetReviewInfo =
                                new PatchsetReviewInfo(maintainersIndex, patchList, currentVerificators);

                        if (patchsetReviewInfo.getReviewState() == ALL_COMPONENTS_REVIEWED) {
                            LOG.info("All relevant component reviewers verified patchset {}", currentPatchset.getId());
                            approvalPusher.approvePatchset(change, currentPatchset, settings.getPluginUserName());

                            if (settings.isAutoSubmit()) {
                                LOG.info("Submitting change {}", change.getId());
                                submitPusher.submitPatch(change, settings.getPluginUserName());
                            } else {
                                LOG.warn("Auto submit turned off");
                            }
                        } else if (patchsetReviewInfo.getReviewState() == COMMITTER_ATTENTION_NEEDED) {
                            LOG.info("Patchset {} affects no configured components, committers attention needed",
                                    currentPatchset.getId());
                        } else {
                            LOG.info(
                                    "Patchset {} does not have verifications from following components yet : {}",
                                    currentPatchset.getId(), patchsetReviewInfo.getMissingComponentReview());
                        }
                    }
                }
            } catch (OrmException e) {
                LOG.error("Error accessing review DB", e);
                throw new IllegalStateException(e);
            }
        }
    }

    @Override
    protected boolean canConsume(final Event event) {
        return event instanceof CommentAddedEvent;
    }
}
