package org.puller.comixology;

import com.squareup.okhttp.OkHttpClient;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.puller.Comic;
import retrofit.RestAdapter;
import retrofit.client.OkClient;

import java.net.CookieManager;
import java.net.CookiePolicy;
import java.time.LocalDate;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;

public class Comixology {
    private static final String COMIXOLOGY_PULL_LIST_BASE_URL = "https://pulllist.comixology.com/";

    private final ComixologyUser user;
    private final ComixologyService service;

    private boolean isNotLoggedIn = true;

    public Comixology(final String username, final String password) {
        this.user = new ComixologyUser(username, password);
        this.service = createService();
    }

    private ComixologyService createService() {
        final CookieManager cookieManager = new CookieManager();
        cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);

        final OkHttpClient httpClient = new OkHttpClient();
        httpClient.setCookieHandler(cookieManager);

        final RestAdapter restAdapter = new RestAdapter.Builder()
                .setEndpoint(COMIXOLOGY_PULL_LIST_BASE_URL)
                .setClient(new OkClient(httpClient))
                .setConverter(new HtmlConverter())
                .build();

        return restAdapter.create(ComixologyService.class);
    }

    public List<Comic> getWeeklyPullList(final LocalDate date) {
        final String csrfToken = getCsrfToken();

        if (isNotLoggedIn) {
            service.login(user.toMap(), csrfToken);
            isNotLoggedIn = false;
        }

        final String year = String.format(Locale.ENGLISH, "%tY", date);
        final String month = String.format(Locale.ENGLISH, "%tm", date);
        final String dayOfMonth = String.format(Locale.ENGLISH, "%td", date);
        final String weeklyPullList = service.getWeeklyPullList(year, month, dayOfMonth);

        return parse(weeklyPullList);
    }

    private List<Comic> parse(final String pullList) {
        final Document document = Jsoup.parse(pullList);

        return document.select("#title > a").stream()
                .map(e -> e.parent().parent())
                .map(e -> new Comic(e.select("#title > a").text(), e.select("#price").text()))
                .collect(Collectors.toList());
    }

    private String getCsrfToken() {
        final String index = service.getIndex();
        return Jsoup.parse(index).select("input[name=PL_CSRF_TOKEN]").attr("value");
    }
}

@@ -512,16 +512,88 @@
 com/%22;%0A%0A
+    private static final String LOGIN_INFO_COOKIE_NAME = %22LOGIN_INFO%22;%0A%0A
     priv
@@ -623,16 +623,16 @@
 r user;%0A
-
     priv
@@ -708,24 +708,94 @@
 In = true;%0A%0A
+    private final CookieManager cookieManager = new CookieManager();%0A%0A
     public C
@@ -1011,73 +1011,8 @@
 ) %7B%0A
-        final CookieManager cookieManager = new CookieManager();%0A
     
@@ -1661,24 +1661,24 @@
 LoggedIn) %7B%0A
-
             
@@ -1716,16 +1716,286 @@
 fToken);
+%0A%0A            // TODO IMPROVE !%0A            cookieManager.getCookieStore().getCookies().stream()%0A                    .filter(c -%3E LOGIN_INFO_COOKIE_NAME.equals(c.getName()))%0A                    .findFirst().orElseThrow(() -%3E new RuntimeException(%22Not authenticated !%22));
 %0A       

Check if user is correctly logged in Comixology