package com.khmelenko.lab.varis.presenter;
import android.text.TextUtils;
import com.khmelenko.lab.varis.event.travis.BuildDetailsLoadedEvent;
import com.khmelenko.lab.varis.event.travis.CancelBuildFailedEvent;
import com.khmelenko.lab.varis.event.travis.CancelBuildSuccessEvent;
import com.khmelenko.lab.varis.event.travis.IntentUrlSuccessEvent;
import com.khmelenko.lab.varis.event.travis.LoadingFailedEvent;
import com.khmelenko.lab.varis.event.travis.LogFailEvent;
import com.khmelenko.lab.varis.event.travis.LogLoadedEvent;
import com.khmelenko.lab.varis.event.travis.RestartBuildFailedEvent;
import com.khmelenko.lab.varis.event.travis.RestartBuildSuccessEvent;
import com.khmelenko.lab.varis.mvp.MvpPresenter;
import com.khmelenko.lab.varis.network.response.BuildDetails;
import com.khmelenko.lab.varis.network.response.Job;
import com.khmelenko.lab.varis.storage.AppSettings;
import com.khmelenko.lab.varis.storage.CacheStorage;
import com.khmelenko.lab.varis.task.TaskError;
import com.khmelenko.lab.varis.task.TaskManager;
import com.khmelenko.lab.varis.view.BuildDetailsView;
import java.net.MalformedURLException;
import java.net.URL;
import javax.inject.Inject;
import de.greenrobot.event.EventBus;
/**
* Presenter for BuildDetails
*
* @author Dmytro Khmelenko (d.khmelenko@gmail.com)
*/
public class BuildsDetailsPresenter extends MvpPresenter<BuildDetailsView> {
public static final int LOAD_LOG_MAX_ATTEMPT = 3;
public final EventBus mEventBus;
public final TaskManager mTaskManager;
public final CacheStorage mCache;
private String mRepoSlug;
private long mBuildId;
private long mJobId;
private int mLoadLogAttempt = 0;
@Inject
public BuildsDetailsPresenter(EventBus eventBus, TaskManager taskManager, CacheStorage cache) {
mEventBus = eventBus;
mTaskManager = taskManager;
mCache = cache;
}
@Override
public void onAttach() {
mEventBus.register(this);
}
@Override
public void onDetach() {
mEventBus.unregister(this);
}
/**
* Starts loading log file
*
* @param jobId Job ID
*/
public void startLoadingLog(long jobId) {
mJobId = jobId;
String accessToken = AppSettings.getAccessToken();
if (TextUtils.isEmpty(accessToken)) {
mTaskManager.getLogUrl(jobId);
} else {
String auth = String.format("token %1$s", AppSettings.getAccessToken());
mTaskManager.getLogUrl(auth, jobId);
}
}
/**
* Starts loading data
*
* @param intentUrl Intent URL
* @param repoSlug Repository slug
* @param buildId Build ID
*/
public void startLoadingData(String intentUrl, String repoSlug, long buildId) {
mRepoSlug = repoSlug;
mBuildId = buildId;
if (!TextUtils.isEmpty(intentUrl)) {
mTaskManager.intentUrl(intentUrl);
} else {
mTaskManager.getBuildDetails(mRepoSlug, mBuildId);
}
getView().showProgress();
}
/**
* Raised on failed loading data
*
* @param event Event data
*/
public void onEvent(LoadingFailedEvent event) {
getView().hideProgress();
getView().updateBuildDetails(null);
getView().showLoadingError(event.getTaskError().getMessage());
}
/**
* Raised on failed loading log data
*
* @param event Event data
*/
public void onEvent(LogFailEvent event) {
if(mLoadLogAttempt >= LOAD_LOG_MAX_ATTEMPT) {
getView().showLogError();
getView().showLoadingError(event.getTaskError().getMessage());
} else {
mLoadLogAttempt++;
startLoadingLog(mJobId);
}
}
/**
* Raised on success build restart
*
* @param event Event data
*/
public void onEvent(RestartBuildSuccessEvent event) {
// reload build details
mTaskManager.getBuildDetails(mRepoSlug, mBuildId);
}
/**
* Raised on failed build restart
*
* @param event Event data
*/
public void onEvent(RestartBuildFailedEvent event) {
getView().showLoadingError(event.getTaskError().getMessage());
// reload build details
mTaskManager.getBuildDetails(mRepoSlug, mBuildId);
}
/**
* Raised on success build cancel
*
* @param event Event data
*/
public void onEvent(CancelBuildSuccessEvent event) {
// reload build details
mTaskManager.getBuildDetails(mRepoSlug, mBuildId);
}
/**
* Raised on failed build cancel
*
* @param event Event data
*/
public void onEvent(CancelBuildFailedEvent event) {
getView().showLoadingError(event.getTaskError().getMessage());
// reload build details
mTaskManager.getBuildDetails(mRepoSlug, mBuildId);
}
/**
* Raised on loaded url for the log file
*
* @param event Event data
*/
public void onEvent(LogLoadedEvent event) {
getView().setLogUrl(event.getLogUrl());
}
/**
* Raised on finished intent URL
*
* @param event Event data
*/
public void onEvent(IntentUrlSuccessEvent event) {
parseIntentUrl(event.getRedirectUrl());
boolean isError = TextUtils.isEmpty(mRepoSlug) || mBuildId == 0;
if (isError) {
// handle error
TaskError taskError = new TaskError(TaskError.NETWORK_ERROR, "");
onEvent(new LoadingFailedEvent(taskError));
} else {
mTaskManager.getBuildDetails(mRepoSlug, mBuildId);
}
}
/**
* Raised on loaded build details
*
* @param event Event data
*/
public void onEvent(BuildDetailsLoadedEvent event) {
getView().hideProgress();
getView().updateBuildDetails(event.getBuildDetails());
BuildDetails details = event.getBuildDetails();
if (details != null) {
if (details.getJobs().size() > 1) {
getView().showBuildJobs(details.getJobs());
} else if (details.getJobs().size() == 1) {
getView().showBuildLogs();
Job job = details.getJobs().get(0);
startLoadingLog(job.getId());
}
// if user logged in, show additional actions for the repo
String appToken = AppSettings.getAccessToken();
if (!TextUtils.isEmpty(appToken)) {
getView().showAdditionalActionsForBuild(details);
}
}
}
/**
* Parses intent URL
*
* @param intentUrl Intent URL
*/
private void parseIntentUrl(String intentUrl) {
final int ownerIndex = 1;
final int repoNameIndex = 2;
final int buildIdIndex = 4;
final int pathLength = 5;
try {
URL url = new URL(intentUrl);
String path = url.getPath();
String[] items = path.split("/");
if (items.length >= pathLength) {
mRepoSlug = String.format("%s/%s", items[ownerIndex], items[repoNameIndex]);
mBuildId = Long.valueOf(items[buildIdIndex]);
}
} catch (MalformedURLException | NumberFormatException e) {
e.printStackTrace();
}
}
/**
* Restarts build process
*/
public void restartBuild() {
mTaskManager.restartBuild(mBuildId);
}
/**
* Cancels build process
*/
public void cancelBuild() {
mTaskManager.cancelBuild(mBuildId);
}
/**
* Defines whether the user can contribute to the repository or not
*
* @return True if user can contribute to the repository. False otherwise
*/
public boolean canUserContributeToRepo() {
boolean canContributeToRepo = false;
String[] userRepos = mCache.restoreRepos();
for (String repo : userRepos) {
if (repo.equals(mRepoSlug)) {
canContributeToRepo = true;
break;
}
}
return canContributeToRepo;
}
}