content: /*
   * Copyright (C) 2017 MINDORKS NEXTGEN PRIVATE LIMITED
   * 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
   *
   *     https://mindorks.com/license/apache-v2
   *
   * 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 <%= appPackage %>.ui.base;
  
  /**
   * Created by janisharali on 27/01/17.
   */
  
  import android.util.Log;
  
  import com.androidnetworking.common.ANConstants;
  import com.androidnetworking.error.ANError;
  import com.google.gson.Gson;
  import com.google.gson.GsonBuilder;
  import com.google.gson.JsonSyntaxException;
  import <%= appPackage %>.R;
  import <%= appPackage %>.data.network.model.ApiError;
  import <%= appPackage %>.utils.AppConstants;
  import <%= appPackage %>.utils.rx.SchedulerProvider;
  
  import javax.inject.Inject;
  import javax.net.ssl.HttpsURLConnection;
  
  import io.reactivex.disposables.CompositeDisposable;
  
  /**
   * Base class that implements the Presenter interface and provides a base implementation for
   * onAttach() and onDetach(). It also handles keeping a reference to the mvpView that
   * can be accessed from the children classes by calling getMvpView().
   */
  public class BasePresenter<V extends MvpView, I extends MvpInteractor>
          implements MvpPresenter<V, I> {
  
      private static final String TAG = "BasePresenter";
  
      private final SchedulerProvider mSchedulerProvider;
      private final CompositeDisposable mCompositeDisposable;
  
      private V mMvpView;
      private I mMvpInteractor;
  
      @Inject
      public BasePresenter(I mvpInteractor,
                           SchedulerProvider schedulerProvider,
                           CompositeDisposable compositeDisposable) {
          mMvpInteractor = mvpInteractor;
          mSchedulerProvider = schedulerProvider;
          mCompositeDisposable = compositeDisposable;
      }
  
      @Override
      public void onAttach(V mvpView) {
          mMvpView = mvpView;
      }
  
      @Override
      public void onDetach() {
          mCompositeDisposable.dispose();
          mMvpView = null;
          mMvpInteractor = null;
      }
  
      @Override
      public V getMvpView() {
          return mMvpView;
      }
  
      @Override
      public I getInteractor() {
          return mMvpInteractor;
      }
  
      @Override
      public boolean isViewAttached() {
          return mMvpView != null;
      }
  
      @Override
      public void checkViewAttached() throws MvpViewNotAttachedException {
          if (!isViewAttached()) throw new MvpViewNotAttachedException();
      }
  
      public SchedulerProvider getSchedulerProvider() {
          return mSchedulerProvider;
      }
  
      public CompositeDisposable getCompositeDisposable() {
          return mCompositeDisposable;
      }
  
      @Override
      public void handleApiError(ANError error) {
  
          if (error == null || error.getErrorBody() == null) {
              getMvpView().onError(R.string.api_default_error);
              return;
          }
  
          if (error.getErrorCode() == AppConstants.API_STATUS_CODE_LOCAL_ERROR
                  && error.getErrorDetail().equals(ANConstants.CONNECTION_ERROR)) {
              getMvpView().onError(R.string.connection_error);
              return;
          }
  
          if (error.getErrorCode() == AppConstants.API_STATUS_CODE_LOCAL_ERROR
                  && error.getErrorDetail().equals(ANConstants.REQUEST_CANCELLED_ERROR)) {
              getMvpView().onError(R.string.api_retry_error);
              return;
          }
  
          final GsonBuilder builder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation();
          final Gson gson = builder.create();
  
          try {
              ApiError apiError = gson.fromJson(error.getErrorBody(), ApiError.class);
  
              if (apiError == null || apiError.getMessage() == null) {
                  getMvpView().onError(R.string.api_default_error);
                  return;
              }
  
              switch (error.getErrorCode()) {
                  case HttpsURLConnection.HTTP_UNAUTHORIZED:
                  case HttpsURLConnection.HTTP_FORBIDDEN:
                      setUserAsLoggedOut();
                      getMvpView().openActivityOnTokenExpire();
                  case HttpsURLConnection.HTTP_INTERNAL_ERROR:
                  case HttpsURLConnection.HTTP_NOT_FOUND:
                  default:
                      getMvpView().onError(apiError.getMessage());
              }
          } catch (JsonSyntaxException | NullPointerException e) {
              Log.e(TAG, "handleApiError", e);
              getMvpView().onError(R.string.api_default_error);
          }
      }
  
      @Override
      public void setUserAsLoggedOut() {
          getInteractor().setAccessToken(null);
      }
  
      public static class MvpViewNotAttachedException extends RuntimeException {
          public MvpViewNotAttachedException() {
              super("Please call Presenter.onAttach(MvpView) before" +
                      " requesting data to the Presenter");
          }
      }
  }
  