// Copyright (C) 2011 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.google.gerrit.server.git;

import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.project.ProjectCache;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;

import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.PersonIdent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class RenameGroupOp extends DefaultQueueOp {
  public interface Factory {
    RenameGroupOp create(@Assisted("author") PersonIdent author,
        @Assisted AccountGroup.UUID uuid, @Assisted("oldName") String oldName,
        @Assisted("newName") String newName);
  }

  private static final int MAX_TRIES = 10;
  private static final Logger log =
      LoggerFactory.getLogger(RenameGroupOp.class);

  private final ProjectCache projectCache;
  private final MetaDataUpdate.Server metaDataUpdateFactory;

  private final PersonIdent author;
  private final AccountGroup.UUID uuid;
  private final String oldName;
  private final String newName;
  private final List<Project.NameKey> retryOn;

  private boolean tryingAgain;

  @Inject
  public RenameGroupOp(WorkQueue workQueue, ProjectCache projectCache,
      MetaDataUpdate.Server metaDataUpdateFactory,

      @Assisted("author") PersonIdent author, @Assisted AccountGroup.UUID uuid,
      @Assisted("oldName") String oldName, @Assisted("newName") String newName) {
    super(workQueue);
    this.projectCache = projectCache;
    this.metaDataUpdateFactory = metaDataUpdateFactory;

    this.author = author;
    this.uuid = uuid;
    this.oldName = oldName;
    this.newName = newName;
    this.retryOn = new ArrayList<>();
  }

  @Override
  public void run() {
    Iterable<Project.NameKey> names = tryingAgain
        ? retryOn
        : projectCache.all();
    for (Project.NameKey projectName : names) {
      ProjectConfig config = projectCache.get(projectName).getConfig();
      GroupReference ref = config.getGroup(uuid);
      if (ref == null || newName.equals(ref.getName())) {
        continue;
      }

      try {
        MetaDataUpdate md = metaDataUpdateFactory.create(projectName);
        try {
          rename(md);
        } finally {
          md.close();
        }
      } catch (RepositoryNotFoundException noProject) {
        continue;
      } catch (ConfigInvalidException err) {
        log.error("Cannot rename group " + oldName + " in " + projectName, err);
      } catch (IOException err) {
        log.error("Cannot rename group " + oldName + " in " + projectName, err);
      }
    }

    // If one or more projects did not update, wait 5 minutes
    // and give it another attempt.
    if (!retryOn.isEmpty() && !tryingAgain) {
      tryingAgain = true;
      start(5, TimeUnit.MINUTES);
    }
  }

  private void rename(MetaDataUpdate md) throws IOException,
      ConfigInvalidException {
    boolean success = false;
    for (int attempts = 0; !success && attempts < MAX_TRIES; attempts++) {
      ProjectConfig config = ProjectConfig.read(md);

      // The group isn't referenced, or its name has been fixed already.
      //
      GroupReference ref = config.getGroup(uuid);
      if (ref == null || newName.equals(ref.getName())) {
        projectCache.evict(config.getProject());
        return;
      }

      ref.setName(newName);
      md.getCommitBuilder().setAuthor(author);
      md.setMessage("Rename group " + oldName + " to " + newName + "\n");
      try {
        config.commit(md);
        projectCache.evict(config.getProject());
        success = true;
      } catch (IOException e) {
        log.error("Could not commit rename of group " + oldName + " to "
            + newName + " in " + md.getProjectName().get(), e);
        try {
          Thread.sleep(25 /* milliseconds */);
        } catch (InterruptedException wakeUp) {
          continue;
        }
      }
    }

    if (!success) {
      if (tryingAgain) {
        log.warn("Could not rename group " + oldName + " to " + newName
            + " in " + md.getProjectName().get());
      } else {
        retryOn.add(md.getProjectName());
      }
    }
  }

  @Override
  public String toString() {
    return "Rename Group " + oldName;
  }
}
