package com.morihacky.android.rxjava.fragments;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import com.morihacky.android.rxjava.R;
import com.morihacky.android.rxjava.retrofit.Contributor;
import com.morihacky.android.rxjava.retrofit.GithubApi;
import com.morihacky.android.rxjava.retrofit.GithubService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
import java.util.concurrent.TimeUnit;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
import timber.log.Timber;

public class PseudoCacheMergeFragment
      extends BaseFragment {

    @Bind(R.id.log_list) ListView _resultList;

    private ArrayAdapter<String> _adapter;
    private HashMap<String, Long> _contributionMap = null;
    private HashMap<Contributor, Long> _resultAgeMap = new HashMap<>();

    @Override
    public View onCreateView(LayoutInflater inflater,
                             @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        View layout = inflater.inflate(R.layout.fragment_pseudo_cache_concat, container, false);
        ButterKnife.bind(this, layout);
        _initializeCache();
        return layout;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        ButterKnife.unbind(this);
    }

    @OnClick(R.id.btn_start_pseudo_cache)
    public void onDemoPseudoCacheClicked() {
        _adapter = new ArrayAdapter<>(getActivity(), R.layout.item_log, R.id.item_log, new ArrayList<>());

        _resultList.setAdapter(_adapter);
        _initializeCache();


        _getFreshData()//
              .publish(fd -> Observable.merge(fd, _getCachedData().takeUntil(fd)))
              //Observable.merge(_getCachedData(), _getFreshData())
              .subscribeOn(Schedulers.io())
              .observeOn(AndroidSchedulers.mainThread())
              .subscribe(new Subscriber<Pair<Contributor, Long>>() {
                  @Override
                  public void onCompleted() {
                      Timber.d("done loading all data");
                  }

                  @Override
                  public void onError(Throwable e) {
                      Timber.e(e, "arr something went wrong");
                  }

                  @Override
                  public void onNext(Pair<Contributor, Long> contributorAgePair) {
                      Contributor contributor = contributorAgePair.first;

                      //if (_resultAgeMap.containsKey(contributor) &&
                      //    _resultAgeMap.get(contributor) > contributorAgePair.second) {
                      //    return;
                      //}

                      _contributionMap.put(contributor.login, contributor.contributions);
                      //_resultAgeMap.put(contributor, contributorAgePair.second);

                      _adapter.clear();
                      _adapter.addAll(getListStringFromMap());
                  }
              });
    }

    private List<String> getListStringFromMap() {
        List<String> list = new ArrayList<>();

        for (String username : _contributionMap.keySet()) {
            String rowLog = String.format("%s [%d]", username, _contributionMap.get(username));
            list.add(rowLog);
        }

        return list;
    }

    private Observable<Pair<Contributor, Long>> _getCachedData() {

        List<Pair<Contributor, Long>> list = new ArrayList<>();

        Pair<Contributor, Long> dataWithAgePair;

        for (String username : _contributionMap.keySet()) {
            Contributor c = new Contributor();
            c.login = username;
            c.contributions = _contributionMap.get(username);

            dataWithAgePair = new Pair<>(c, System.currentTimeMillis());
            list.add(dataWithAgePair);
        }

        return Observable.from(list).delay(5, TimeUnit.SECONDS);
    }

    private Observable<Pair<Contributor, Long>> _getFreshData() {
        String githubToken = getResources().getString(R.string.github_oauth_token);
        GithubApi githubService = GithubService.createGithubService(githubToken);

        return githubService.contributors("square", "retrofit")
              .flatMap(Observable::from)
              .map(contributor -> new Pair<>(contributor, System.currentTimeMillis()));
    }

    private void _initializeCache() {
        _contributionMap = new HashMap<>();
        _contributionMap.put("JakeWharton", 0l);
        _contributionMap.put("pforhan", 0l);
        _contributionMap.put("edenman", 0l);
        _contributionMap.put("swankjesse", 0l);
        _contributionMap.put("bruceLee", 0l);
    }
}

@@ -299,17 +299,101 @@
 stView;%0A
+import butterknife.Bind;%0Aimport butterknife.ButterKnife;%0Aimport butterknife.OnClick;
 %0A
-
 import c
@@ -597,17 +597,16 @@
 ervice;%0A
-%0A
 import j
@@ -677,132 +677,8 @@
 ist;
-%0A%0Aimport butterknife.Bind;%0Aimport butterknife.ButterKnife;%0Aimport butterknife.OnClick;%0Aimport java.util.concurrent.TimeUnit;
 %0Aimp
@@ -1894,25 +1894,24 @@
 che();%0A%0A
-%0A
         
 _getFres
@@ -1906,125 +1906,8 @@
     
-_getFreshData()//%0A              .publish(fd -%3E Observable.merge(fd, _getCachedData().takeUntil(fd)))%0A              //
 Obse
@@ -2649,18 +2649,16 @@
         
-//
 if (_res
@@ -2713,26 +2713,24 @@
             
-//
     _resultA
@@ -2805,18 +2805,16 @@
         
-//
     retu
@@ -2839,18 +2839,16 @@
         
-//
 %7D%0A%0A     
@@ -2958,10 +2958,8 @@
     
-//
 _res
@@ -3985,32 +3985,32 @@
 ir);%0A        %7D%0A%0A
+
         return O
@@ -4033,35 +4033,8 @@
 ist)
-.delay(5, TimeUnit.SECONDS)
 ;%0A  

revert pseudo cache merge fragment to old code