package com.alorma.github;
import android.content.Context;
import android.content.Intent;
import android.content.UriMatcher;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.alorma.github.sdk.bean.info.CommitInfo;
import com.alorma.github.sdk.bean.info.FileInfo;
import com.alorma.github.sdk.bean.info.IssueInfo;
import com.alorma.github.sdk.bean.info.ReleaseInfo;
import com.alorma.github.sdk.bean.info.RepoInfo;
import com.alorma.github.ui.ErrorHandler;
import com.alorma.github.ui.activity.CommitDetailActivity;
import com.alorma.github.ui.activity.FileActivity;
import com.alorma.github.ui.activity.IssueDetailActivity;
import com.alorma.github.ui.activity.ProfileActivity;
import com.alorma.github.ui.activity.PullRequestDetailActivity;
import com.alorma.github.ui.activity.ReleaseDetailActivity;
import com.alorma.github.ui.activity.repo.RepoDetailActivity;
import com.crashlytics.android.Crashlytics;
import core.User;
import io.fabric.sdk.android.Fabric;
public class IntentsManager {
private static final int URI_BASE = 0;
private static final int URI_USER = 1;
private static final int URI_REPO = 2;
private static final int URI_REPO_NUMS = 16;
private static final int URI_REPO_NUMS2 = 17;
private static final int URI_REPO_NUMS3 = 18;
private static final int URI_ISSUE = 3;
private static final int URI_COMMIT = 4;
private static final int URI_REPO_BRANCH = 5;
private static final int URI_REPO_BRANCH_FEATURE = 6;
private static final int URI_REPO_BRANCH_RELEASE = 7;
private static final int URI_REPO_BRANCH_HOTFIX = 8;
private static final int URI_RELEASES_TAG = 9;
private static final int URI_RELEASES = 10;
private static final int URI_RELEASES_IDENTIFIER = 11;
private static final int URI_RELEASES_LATEST = 12;
private static final int URI_TAGS = 13;
private static final int URI_PULL_REQUEST = 14;
private static final int URI_ISSUE_COMMENT = 15;
private final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
private final GitskariosUriManager gitsakriosUriManager = new GitskariosUriManager();
private Context context;
public IntentsManager(Context context) {
this.context = context;
int i = 1000;
String host = "github.com";
StoreCredentials credentials = new StoreCredentials(context);
if (credentials.getUrl() != null) {
Uri uri = Uri.parse(credentials.getUrl());
host = uri.getAuthority();
if (host == null) {
host = credentials.getUrl();
}
if (host != null) {
if (!host.startsWith("http://")) {
host = "http://" + host;
}
Uri newUri = Uri.parse(host);
if (!"https".equals(newUri.getScheme())) {
newUri = newUri.buildUpon().scheme("https").build();
}
host = newUri.getAuthority();
}
}
uriMatcher.addURI(host, "", URI_BASE + i);
for (String key : context.getResources().getStringArray(R.array.reservedKeys)) {
uriMatcher.addURI(host, key, UriMatcher.NO_MATCH + i++);
}
uriMatcher.addURI(host, "*/*/releases", URI_RELEASES);
uriMatcher.addURI(host, "*/*/releases/#", URI_RELEASES_IDENTIFIER);
uriMatcher.addURI(host, "*/*/tags", URI_TAGS);
uriMatcher.addURI(host, "*/*/commit/*", URI_COMMIT);
uriMatcher.addURI(host, "*/*/issues/comments/#", URI_ISSUE_COMMENT);
uriMatcher.addURI(host, "*/*/issues/#", URI_ISSUE);
uriMatcher.addURI(host, "*/*/pull/#", URI_PULL_REQUEST);
uriMatcher.addURI(host, "*/*/tree/feature/*", URI_REPO_BRANCH_FEATURE);
uriMatcher.addURI(host, "*/*/tree/release/*", URI_REPO_BRANCH_RELEASE);
uriMatcher.addURI(host, "*/*/tree/hotfix/*", URI_REPO_BRANCH_HOTFIX);
uriMatcher.addURI(host, "*/*/tree/*", URI_REPO_BRANCH);
uriMatcher.addURI(host, "*/*", URI_REPO);
uriMatcher.addURI(host, "*/#", URI_REPO_NUMS);
uriMatcher.addURI(host, "#/*", URI_REPO_NUMS2);
uriMatcher.addURI(host, "#/#", URI_REPO_NUMS3);
uriMatcher.addURI(host, "*", URI_USER);
}
public void manageUrls(final WebView webView) {
webView.getSettings().setUseWideViewPort(true);
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Intent intent = checkUri(Uri.parse(url));
if (intent != null) {
view.getContext().startActivity(intent);
} else {
Intent intentView = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
view.getContext().startActivity(intentView);
}
return true;
}
});
}
@Nullable
public Intent checkUri(Uri uri) {
uri = normalizeUri(uri);
boolean matched = uriMatcher.match(uri) > -1 && uriMatcher.match(uri) < 1000;
Intent intent = null;
if (matched) {
switch (uriMatcher.match(uri)) {
case URI_REPO:
case URI_REPO_NUMS:
case URI_REPO_NUMS2:
case URI_REPO_NUMS3:
case URI_REPO_BRANCH:
case URI_REPO_BRANCH_FEATURE:
case URI_REPO_BRANCH_RELEASE:
case URI_REPO_BRANCH_HOTFIX:
intent = manageRepos(uri);
break;
case URI_USER:
intent = manageUsers(uri);
break;
case URI_COMMIT:
intent = manageCommit(uri);
break;
case URI_ISSUE:
intent = manageIssue(uri);
break;
case URI_PULL_REQUEST:
intent = manageIssuePullRequest(uri);
break;
case URI_RELEASES_IDENTIFIER:
intent = manageReleasesWithId(uri);
break;
case URI_RELEASES:
case URI_RELEASES_LATEST:
case URI_RELEASES_TAG:
case URI_TAGS:
case URI_ISSUE_COMMENT:
if (Fabric.isInitialized()) {
Crashlytics.log(uri.toString());
} else {
ErrorHandler.onError(context, "Interceptor", new UriNotHandledException(uri));
}
break;
}
} else if (uri.toString().contains("blob")) {
intent = manageFile(uri);
} else {
if (Fabric.isInitialized()) {
Crashlytics.log(uri.toString());
}
}
return intent;
}
private Uri normalizeUri(Uri uri) {
if (uri != null && uri.getAuthority() != null) {
if (uri.getPath().contains("/api/v3/")) {
String authority = uri.getPath().replace("/api/v3/", "/");
uri = uri.buildUpon().path(authority).build();
} else if (uri.getAuthority().contains("api.")) {
String authority = uri.getAuthority().replace("api.", "");
uri = uri.buildUpon().authority(authority).build();
}
if (uri.getPath().contains("repos/")) {
String path = uri.getPath().replace("repos/", "");
uri = uri.buildUpon().path(path).build();
}
if (uri.getPath().contains("commits/")) {
String path = uri.getPath().replace("commits/", "commit/");
uri = uri.buildUpon().path(path).build();
}
if (uri.getPath().contains("pulls/")) {
String path = uri.getPath().replace("pulls/", "pull/");
uri = uri.buildUpon().path(path).build();
}
}
return uri;
}
public Intent manageRepos(Uri uri) {
uri = normalizeUri(uri);
RepoInfo repoInfo = gitsakriosUriManager.getRepoInfo(uri);
if (Fabric.isInitialized()) {
Crashlytics.log(uri.toString());
}
return RepoDetailActivity.createLauncherIntent(context, repoInfo);
}
public Intent manageUsers(Uri uri) {
User user = gitsakriosUriManager.getUser(uri);
return ProfileActivity.createLauncherIntent(context, user);
}
private Intent manageCommit(Uri uri) {
CommitInfo info = gitsakriosUriManager.getCommitInfo(uri);
return CommitDetailActivity.launchIntent(context, info);
}
private Intent manageIssue(Uri uri) {
IssueInfo info = gitsakriosUriManager.getIssueCommentInfo(uri);
return IssueDetailActivity.createLauncherIntent(context, info);
}
private Intent manageIssuePullRequest(Uri uri) {
IssueInfo info = gitsakriosUriManager.getIssueInfo(uri);
return PullRequestDetailActivity.createLauncherIntent(context, info);
}
private Intent manageReleasesWithId(Uri uri) {
ReleaseInfo info = gitsakriosUriManager.getReleaseInfo(uri);
return ReleaseDetailActivity.launchIntent(context, info);
}
private Intent manageFile(Uri uri) {
FileInfo info = gitsakriosUriManager.getFileInfo(uri);
return FileActivity.createLauncherIntent(context, info);
}
}