// 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.reviewdb.client.Project.NameKey;
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<Project.NameKey>();
  }

  @Override
  public void run() {
    Iterable<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");
      if (config.commit(md)) {
        projectCache.evict(config.getProject());
        success = true;

      } else {
        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;
  }
}
