private void initCache(List<SectionModel> sections) {

    if (!CommonUtil.isEmpty(sections)) {
      int size = sections.size();
      mTopSections = new ArrayList<>(size);
      mDetailSections = new HashMap<>(size);
    }
  }
  private void initCache(RawViaplayModel model) {

    if (model != null && !CommonUtil.isEmpty(model.getSections())) {
      int size = model.getSections().size();
      mTopSections = new ArrayList<>(size);
      mDetailSections = new HashMap<>(size);
    }
  }
  @WorkerThread
  public void getSpecificSection(
      Context context, int sectionPos, OnSectionDetailReadyListener listener) {

    SectionModel section = mTopSections.get(sectionPos);

    String sectionName = section.getName();

    if (CommonUtil.isEmpty(mDetailSections) || !mDetailSections.containsKey(sectionName)) {

      if (CommonUtil.checkInternetConnection(context)) {

        // try downloading data from web

        RawViaplayModel detail = null;

        try {

          detail = getSectionFromWeb(section.getUrl());

          populateSectionDetailCache(section, detail);

          returnSectionDetailToListener(sectionName, listener);

          DatabaseManager.getInstance()
              .saveDataToDb(SectionDetailModel.generateFrom(detail, section));

        } catch (IOException e) {
          Log.e(TAG, "Error while downloading section");
        }
      } else {

        // try retrieving data from db
        SectionDetailModel detail = DatabaseManager.getInstance().getSectionDetailFromDb(section);
        populateSectionDetailCache(section, detail);
        returnSectionDetailToListener(sectionName, listener);
      }

    } else {

      Log.d(TAG, "Retrieving data from cache");
      returnSectionDetailToListener(sectionName, listener);
    }
  }
  @WorkerThread
  public void getAllSections(Context context, OnAllSectionsReadyListener listener) {

    if (CommonUtil.isEmpty(mTopSections)) {

      if (CommonUtil.checkInternetConnection(context)) {

        // try getting data from web

        RawViaplayModel model = null;

        try {

          model = getAllSectionsFromWeb();
          initCache(model);
          populateTopSectionsCache(model);
          returnAllSectionsToListener(listener);
          DatabaseManager.getInstance().saveDataToDb(mTopSections);

        } catch (IOException e) {
          Log.e(TAG, "Error while retrieving data from web");
        }

      } else {
        // try getting data from db

        List<SectionModel> models = DatabaseManager.getInstance().getAllSectionsFromDb();
        initCache(models);
        populateTopSectionsCache(models);
        returnAllSectionsToListener(listener);
      }

    } else {

      Log.d(TAG, "Retrieving data from cache");
      returnAllSectionsToListener(listener);
    }
  }
  private RawViaplayModel getAllSectionsFromWeb() throws IOException {

    Log.d(TAG, "Retrieving data from web api");

    RawViaplayModel model = null;

    Call<RawViaplayModel> call = mApiInterface.getAllSections();

    Response<RawViaplayModel> response = call.execute();

    if (response != null
        && response.body() != null
        && !CommonUtil.isEmpty(response.body().getSections())) {

      model = response.body();
    }

    return model;
  }
 private void returnAllSectionsToListener(OnAllSectionsReadyListener listener) {
   if (listener != null && !CommonUtil.isEmpty(mTopSections))
     listener.onAllSectionsReady(Collections.unmodifiableList(mTopSections));
 }
  private void populateTopSectionsCache(List<SectionModel> sections) {

    if (!CommonUtil.isEmpty(sections)) mTopSections.addAll(sections);
  }