// 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.github.git;

import com.googlesource.gerrit.plugins.github.git.GitJobStatus.Code;
import org.eclipse.jgit.lib.ProgressMonitor;

public class GitImportJob extends AbstractCloneJob implements Runnable, ProgressMonitor, GitJob {
  private int currTask;
  private int totUnits;
  private int currUnit;
  private int lastPercentage;
  private boolean cancelled;
  private String task = "Waiting ...";
  private Exception exception;
  private GitJobStatus status;
  private int index;
  private final ImportStep[] importSteps;
  private String organisation;
  private String repository;

  public GitImportJob(int id, String organisation, String repository, ImportStep... steps) {
    this.importSteps = steps;
    this.index = id;
    this.organisation = organisation;
    this.repository = repository;
    this.status = new GitJobStatus(id);
  }

  @Override
  public void run() {
    try {
      status.update(Code.SYNC, "Init", "Initializing import steps ...");
      for (ImportStep importStep : importSteps) {
        importStep.doImport(this);
      }
      status.update(GitJobStatus.Code.COMPLETE, "Done", "Done: repository replicated to Gerrit.");
    } catch (Exception e) {
      if (status.getStatus() == GitJobStatus.Code.SYNC) {
        this.exception = e;
        status.update(GitJobStatus.Code.FAILED, "Failed", getStatusDescription());
      }
      rollback();
    }
  }

  private void rollback() {
    for (ImportStep importStep : importSteps) {
      importStep.rollback();
    }
  }

  @Override
  public void cancel() {
    if (status.getStatus() != GitJobStatus.Code.SYNC) {
      return;
    }

    cancelled = true;
    status.update(GitJobStatus.Code.CANCELLED, "Cancelled", "Cancelled");
    rollback();
  }

  public String getStatusDescription() {
    if (exception != null) {
      return getErrorDescription(exception);
    }

    switch (status.getStatus()) {
      case COMPLETE:
        return "Cloned (100%)";
      case CANCELLED:
        return "Cancelled";
      default:
        return "Phase-" + currTask + " / " + task + " (" + lastPercentage + "%)";
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see com.googlesource.gerrit.plugins.github.git.CloneJob#getStatus()
   */
  @Override
  public GitJobStatus getStatus() {
    return status;
  }

  @Override
  public void update(int completed) {
    if (totUnits == 0) {
      return;
    }

    currUnit += completed;
    int percentage = currUnit * 100 / totUnits;
    if (percentage > lastPercentage) {
      lastPercentage = percentage;
    }

    status.update(Code.SYNC, status.getShortDescription(), getStatusDescription());
  }

  @Override
  public void start(int totalTasks) {
    currTask = 0;
  }

  @Override
  public boolean isCancelled() {
    if (cancelled) {
      status.update(GitJobStatus.Code.CANCELLED);
    }
    return cancelled;
  }

  @Override
  public void endTask() {}

  @Override
  public void beginTask(String taskName, int totalUnits) {
    this.currTask++;
    this.task = taskName;
    this.totUnits = totalUnits;
    this.currUnit = 0;
    this.lastPercentage = 0;

    status.update(Code.SYNC, status.getShortDescription(), getStatusDescription());
  }

  @Override
  public int getIndex() {
    return index;
  }

  @Override
  public String toString() {
    return "CloneJob#" + index + " " + getOrganisation() + "/" + getRepository();
  }

  @Override
  public String getOrganisation() {
    return organisation;
  }

  @Override
  public String getRepository() {
    return repository;
  }
}
