// Copyright (C) 2015 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.importer;

import static com.googlesource.gerrit.plugins.importer.ProgressMonitorUtil.updateAndEnd;

import com.google.inject.Singleton;
import java.io.IOException;
import java.util.Map;
import org.eclipse.jgit.api.FetchCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;

@Singleton
class GitFetchStep {

  void fetch(String user, String password, Repository repo, ProgressMonitor pm)
      throws InvalidRemoteException, TransportException, GitAPIException, IOException {
    pm.beginTask("Fetch project", 1);
    FetchCommand fetch = Git.wrap(repo).fetch();
    if (user != null) {
      fetch.setCredentialsProvider(new UsernamePasswordCredentialsProvider(user, password));
    }
    fetch.setRemote("origin").call();
    updateNonChangeRefs(repo);
    updateAndEnd(pm);
  }

  private void updateNonChangeRefs(Repository repo) throws IOException {
    Map<String, Ref> refs = repo.getRefDatabase().getRefs(ConfigureRepositoryStep.R_IMPORTS);
    for (Map.Entry<String, Ref> e : refs.entrySet()) {
      String name = e.getKey();
      if (name.startsWith("imports/")) {
        continue;
      }
      if (name.startsWith("cache-automerge/")) {
        continue;
      }
      if (name.startsWith("changes/")) {
        continue;
      }
      if (name.startsWith("users/") && name.contains("/edit")) {
        continue;
      }
      String targetRef = Constants.R_REFS + name;
      RefUpdate ru = repo.updateRef(targetRef);
      ru.setNewObjectId(e.getValue().getObjectId());
      RefUpdate.Result result = ru.forceUpdate();
      switch (result) {
        case NEW:
        case FAST_FORWARD:
        case FORCED:
        case NO_CHANGE:
          break;
        case IO_FAILURE:
        case LOCK_FAILURE:
        case NOT_ATTEMPTED:
        case REJECTED:
        case REJECTED_CURRENT_BRANCH:
        case RENAMED:
        default:
          throw new IOException(
              String.format("Failed to update %s, RefUpdate.Result = %s", targetRef, result));
      }
    }
  }
}
