/*
 * 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 static java.lang.String.format;
import static java.util.Objects.nonNull;

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 java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nonnull;
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;

@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 {
                    throw new IllegalStateException(
                            format("Unable to find file %s in branch %s", settings.getLocalFilePath(),
                                    fullFileRef));
                }
            } catch (IOException | MaintainerMismatchException e) {
                throw new IllegalStateException(e);
            }

        } catch (OrmException 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);

        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));
        }
    }
}
