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

import com.github.rholder.retry.Attempt;
import com.github.rholder.retry.RetryListener;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.MultimapBuilder;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.update.RetryHelper;
import com.google.gerrit.server.update.UpdateException;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.TextProgressMonitor;
import org.eclipse.jgit.lib.ThreadSafeProgressMonitor;
import org.kohsuke.args4j.Option;

/** Export review notes for all submitted changes in all projects. */
@CommandMetaData(
    name = "export",
    description = "Export review notes for all submitted changes in all projects")
public class ExportReviewNotes extends SshCommand {
  @Option(name = "--threads", usage = "Number of concurrent threads to run")
  private int threads = 2;

  @Inject private GitRepositoryManager gitManager;

  @Inject private CreateReviewNotes.Factory reviewNotesFactory;

  @Inject private ChangeNotes.Factory notesFactory;

  @Inject private RetryHelper retryHelper;

  private static final Object lock = new Object();

  private ListMultimap<Project.NameKey, ChangeNotes> changes;
  private ThreadSafeProgressMonitor monitor;

  @Override
  protected void run() throws Failure, InterruptedException {
    if (threads <= 0) {
      threads = 1;
    }

    changes = mergedChanges();

    monitor = new ThreadSafeProgressMonitor(new TextProgressMonitor(stdout));
    monitor.beginTask("Scanning merged changes", changes.size());
    monitor.startWorkers(threads);
    for (int tid = 0; tid < threads; tid++) {
      new Worker().start();
    }
    monitor.waitForCompletion();
    monitor.endTask();
  }

  private ListMultimap<Project.NameKey, ChangeNotes> mergedChanges() {
    try {
      return MultimapBuilder.hashKeys()
          .arrayListValues()
          .build(notesFactory.create(notes -> notes.getChange().isMerged()));
    } catch (IOException e) {
      stderr.println("Cannot read changes from database " + e.getMessage());
      return ImmutableListMultimap.of();
    }
  }

  private void export(Project.NameKey project, List<ChangeNotes> notes)
      throws RestApiException, UpdateException {
    retryHelper.execute(
        updateFactory -> {
          try (Repository git = gitManager.openRepository(project)) {
            CreateReviewNotes crn = reviewNotesFactory.create(project, git);
            crn.createNotes(notes, monitor);
            crn.commitNotes();
          } catch (RepositoryNotFoundException e) {
            stderr.println("Unable to open project: " + project.get());
          }
          return null;
        },
        RetryHelper.options()
            .listener(
                new RetryListener() {
                  @Override
                  public <V> void onRetry(Attempt<V> attempt) {
                    monitor.update(-notes.size());
                  }
                })
            .build());
  }

  private Map.Entry<Project.NameKey, List<ChangeNotes>> next() {
    synchronized (lock) {
      if (changes.isEmpty()) {
        return null;
      }

      Project.NameKey name = changes.keySet().iterator().next();
      return Maps.immutableEntry(name, changes.removeAll(name));
    }
  }

  private class Worker extends Thread {
    @Override
    public void run() {
      try {
        for (; ; ) {
          Map.Entry<Project.NameKey, List<ChangeNotes>> next = next();
          if (next != null) {
            try {
              export(next.getKey(), next.getValue());
            } catch (RestApiException | UpdateException e) {
              stderr.println(e.getMessage());
            }
          } else {
            break;
          }
        }
      } finally {
        monitor.endWorker();
      }
    }
  }
}
