package com.quinn.githubknife.interactor;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import com.quinn.githubknife.R;
import com.quinn.githubknife.listener.OnTokenCreatedListener;
import com.quinn.githubknife.model.GithubService;
import com.quinn.githubknife.model.RetrofitUtil;
import com.quinn.githubknife.utils.L;
import com.quinn.githubknife.utils.TDUtils;
import com.quinn.httpknife.github.Empty;
import com.quinn.httpknife.github.Github;
import com.quinn.httpknife.github.GithubImpl;
import com.quinn.httpknife.github.Token;
import com.quinn.httpknife.http.Base64;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Arrays;
import java.util.List;
import retrofit.Call;
import retrofit.Callback;
import retrofit.Response;
import retrofit.Retrofit;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;
/**
* Created by Quinn on 8/1/15.
*/
public class TokenInteractorImpl implements TokenInteractor {
public static final String TAG = TokenInteractorImpl.class.getSimpleName();
private final static int TOKEN_CREATED = 1;
private final static int ERROR = 2;
public final static String TOKEN_NOTE = "WeGit APP Token";
public final static String[] SCOPES = {"public_repo","repo", "user", "gist"};
private OnTokenCreatedListener listener;
private Context context;
private GithubService service;
public TokenInteractorImpl(Context context, final OnTokenCreatedListener listener){
this.context = context;
this.listener = listener;
this.service = RetrofitUtil.getRetrofitWithoutTokenInstance(context).create(GithubService.class);
}
public void createToken(final String username,final String password){
JSONObject json = new JSONObject();
try {
json.put("note", TOKEN_NOTE);
JSONArray jsonArray = new JSONArray(Arrays.asList(SCOPES));
json.put("scopes",jsonArray);
} catch (JSONException e) {
e.printStackTrace();
}
final Token token = new Token();
token.setNote(TOKEN_NOTE);
token.setScopes(Arrays.asList(SCOPES));
service.createToken(token,"Basic " + Base64.encode(username + ':' + password))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Response<Token>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
RetrofitUtil.printThrowable(e);
listener.onError(context.getResources().getString(R.string.network_error));
}
@Override
public void onNext(Response<Token> tokenResponse) {
RetrofitUtil.printResponse(tokenResponse);
if(tokenResponse.isSuccess()){
L.i(TAG, "Token created sucessfully-(new)");
TDUtils.event(R.string.td_event_token_created);
listener.onTokenCreated(tokenResponse.body().getToken());
}else if(tokenResponse.code() == 401){
L.i(TAG,"Token created fail: username or password is incorrect");
listener.onError(context.getResources().getString(R.string.auth_error));
}else if(tokenResponse.code() == 403){
L.i(TAG,"Token created fail: auth over-try");
TDUtils.event(R.string.td_event_token_overtry);
listener.onError(context.getResources().getString(R.string.over_auth_error));
}else if(tokenResponse.code() == 422){
L.i(TAG,"Token created fail: try to delete existing token");
TDUtils.event(R.string.td_event_token_existed);
findCertainTokenID(username,password);
}
}
});
}
public void findCertainTokenID(final String username, final String password){
L.i(TAG,"Find certain token in existing tokens");
service.listToken("Basic " + Base64.encode(username + ':' + password))
.flatMap(new Func1<Response<List<Token>>, Observable<Response<Empty>>>() {
@Override
public Observable<Response<Empty>> call(Response<List<Token>> listResponse) {
RetrofitUtil.printResponse(listResponse);
for(Token token : listResponse.body()){
L.i(TAG,"Find certain token in existing tokens : " +token.getNote() );
if(TOKEN_NOTE.equals(token.getNote())){
return service.removeToken("Basic " + Base64.encode(username + ':' + password), String.valueOf(token.getId()));
}
}
return Observable.empty();
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Response<Empty>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
RetrofitUtil.printThrowable(e);
listener.onError(context.getResources().getString(R.string.network_error));
}
@Override
public void onNext(Response<Empty> listResponse) {
RetrofitUtil.printResponse(listResponse);
if(listResponse.code() == 204){
L.i(TAG,"Deteled token successfully");
L.i(TAG,"Try to get an entirely new token");
createToken(username, password);
}else{
listener.onError(context.getResources().getString(R.string.network_error));
}
}
});
}
}