/*
 * 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.service;

import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import io.fd.maintainer.plugin.parser.ComponentInfo;
import io.fd.maintainer.plugin.parser.MaintainerMismatchException;
import io.fd.maintainer.plugin.parser.MaintainersParser;
import io.fd.maintainer.plugin.service.dto.PluginBranchSpecificSettings;
import io.fd.maintainer.plugin.util.ClosestMatch;
import io.fd.maintainer.plugin.util.PatchListProcessing;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.PathFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Optional;

import static com.google.common.base.Preconditions.checkState;
import static java.lang.String.format;
import static java.util.Objects.nonNull;

@Singleton
public class MaintainersProvider implements ClosestMatch, PatchListProcessing {

    private static final Logger LOG = LoggerFactory.getLogger(MaintainersProvider.class);
    final MaintainersParser maintainersParser;
    @Inject
    private GitRepositoryManager manager;
    @Inject
    private SettingsProvider settingsProvider;
    @Inject
    private SchemaFactory<ReviewDb> schemaFactory;

    public MaintainersProvider() {
        maintainersParser = new MaintainersParser();
    }

    @Nonnull
    public List<ComponentInfo> getMaintainersInfo(@Nonnull final String branchName, final int changeNumber,
                                                  @Nonnull final Project.NameKey projectKey) {
        // get configuration for branch of change
        final PluginBranchSpecificSettings settings =
                settingsProvider.getBranchSpecificSettings(branchName, projectKey);

        try (final ReviewDb reviewDb = schemaFactory.open()) {
            final Change change = reviewDb.changes().get(new Change.Id(changeNumber));
            final String fullFileRef = settings.fullFileRef();

            try (final Repository repository = manager.openRepository(change.getProject())) {

                final Ref ref = Optional.ofNullable(repository.findRef(fullFileRef))
                        .orElseThrow(() -> new IllegalStateException(
                                format("Unable to get ref %s", fullFileRef)));

                final RevCommit revCommit = new RevWalk(repository).parseCommit(ref.getObjectId());

                final String maintainersFileContent =
                        findMostRecentMaintainersChangeContent(settings.getLocalFilePath(), repository,
                                new RevWalk(repository), revCommit);

                if (nonNull(maintainersFileContent)) {
                    return maintainersParser.parseMaintainers(maintainersFileContent);
                } else {
                    LOG.info("Unable to find file {} in branch {}", settings.getLocalFilePath(), fullFileRef);
                    throw new IllegalStateException(
                            format("Unable to find file %s in branch %s", settings.getLocalFilePath(),
                                    fullFileRef));
                }
            }
        } catch (OrmException | IOException | MaintainerMismatchException e) {
            LOG.error("Error while searching maintainers file", e);
            throw new IllegalStateException(e);
        }
    }

    // skips head commit
    private String findMostRecentMaintainersChangeContent(
            final String maintainersFileName,
            final Repository repository,
            final RevWalk revWalk,
            final RevCommit headCommit) {
        LOG.info("Starting search at {}", headCommit);

        checkState(headCommit.getParentCount() > 0, "Bottom of the branch has been reached and maintainers file hasnt been found");
        final RevCommit parent = getRevCommit(revWalk, headCommit.getParent(0).getId());
        LOG.info("Finding most recent maintainers file in {}", parent);

        final String parentIdName = parent.getId().getName();
        LOG.info("Parent commit : {}| id {}", parent.getShortMessage(), parentIdName);

        try (TreeWalk treeWalk = new TreeWalk(repository)) {
            treeWalk.addTree(parent.getTree());
            treeWalk.setRecursive(true);
            treeWalk.setFilter(PathFilter.create(maintainersFileName));
            LOG.info("Attempting to find {}", maintainersFileName);

            if (treeWalk.next()) {
                LOG.info("Maintainers file found in commit {}", parent.getId());
                ObjectId objectId = treeWalk.getObjectId(0);
                ObjectLoader loader = repository.open(objectId);

                // and then one can the loader to read the file
                try (final ByteArrayOutputStream out = new ByteArrayOutputStream()) {
                    loader.copyTo(out);
                    revWalk.dispose();
                    return new String(out.toByteArray());
                }
            }

            LOG.info("Maintainers file not found in commit {}, going deep", parent.getId());
            if (parent.getParents() == null) {
                throw new IllegalStateException(format("Root of branch reached with commit %s", parent));
            }
            return findMostRecentMaintainersChangeContent(maintainersFileName, repository, revWalk, parent);
        } catch (IOException e) {
            throw new IllegalStateException(format("Unable to detect maintainers file in %s", parent.getId()));
        }
    }

    private RevCommit getRevCommit(final RevWalk revWalk, final ObjectId id) {
        try {
            return revWalk.parseCommit(id);
        } catch (IOException e) {
            throw new IllegalStateException(format("Unable to parse commit %s", id));
        }
    }
}
