package cgeo.geocaching.network;

import ch.boye.httpclientandroidlib.client.CookieStore;
import ch.boye.httpclientandroidlib.cookie.Cookie;
import ch.boye.httpclientandroidlib.impl.cookie.BasicClientCookie;
import okhttp3.Cookie.Builder;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import org.apache.commons.lang3.StringUtils;

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

public final class Cookies {

    final static InMemoryCookieJar cookieJar = new InMemoryCookieJar();
    final static CookieStore cookieStore = new CompatibilityCookieStore(cookieJar);

    static class CompatibilityCookieStore implements CookieStore {

        private final InMemoryCookieJar cookieJar;

        CompatibilityCookieStore(final InMemoryCookieJar cookieJar) {
            this.cookieJar = cookieJar;
        }

        @Override
        public void addCookie(final Cookie cookie) {
            final String domain = cookie.getDomain();
            final okhttp3.Cookie newCookie = new Builder()
                    .domain(domain.startsWith(".") ? domain.substring(1) : domain)
                    .name(cookie.getName())
                    .value(cookie.getValue())
                    .build();
            cookieJar.addCookie(newCookie);
        }

        @Override
        public List<Cookie> getCookies() {
            final List<okhttp3.Cookie> allCookies;
            synchronized (cookieJar) {
                allCookies = new ArrayList<>(cookieJar.allCookies.values());
            }
            final List<Cookie> cookies = new ArrayList<>(allCookies.size());
            for (final okhttp3.Cookie cookie: allCookies) {
                final BasicClientCookie newCookie = new BasicClientCookie(cookie.name(), cookie.value());
                newCookie.setDomain('.' + cookie.domain());
                cookies.add(newCookie);
            }
            return cookies;
        }

        @Override
        public boolean clearExpired(final Date date) {
            return false;
        }

        @Override
        public void clear() {
            cookieJar.clear();
        }
    }

    static class InMemoryCookieJar implements CookieJar {

        final HashMap<String, okhttp3.Cookie> allCookies = new HashMap<>();
        private boolean cookieStoreRestored = false;

        @Override
        public synchronized void saveFromResponse(final HttpUrl url, final List<okhttp3.Cookie> cookies) {
            for (final okhttp3.Cookie cookie : cookies) {
                addCookie(cookie);
            }
        }

        private void addCookie(final okhttp3.Cookie cookie) {
            final String key = cookie.domain() + ';' + cookie.name();
            allCookies.put(key, cookie);
        }

        @Override
        public List<okhttp3.Cookie> loadForRequest(final HttpUrl url) {
            final List<okhttp3.Cookie> cookies = new LinkedList<>();
            synchronized(this) {
                for (final okhttp3.Cookie cookie: allCookies.values()) {
                    if (cookie.matches(url)) {
                        cookies.add(cookie);
                    }
                }
            }
            return cookies;
        }

        public synchronized void clear() {
            allCookies.clear();
        }

        public synchronized void restoreCookieStore(final String oldCookies) {
            if (!cookieStoreRestored) {
                clearCookies();
                if (oldCookies != null) {
                    for (final String cookie : StringUtils.split(oldCookies, ';')) {
                        final String[] split = StringUtils.split(cookie, "=", 3);
                        if (split.length == 3) {
                            try {
                                addCookie(new Builder().name(split[0]).value(split[1]).domain(split[2]).build());
                            } catch (final Exception ignored) {
                           }
                        }
                    }
                }
                cookieStoreRestored = true;
            }
        }

        String dumpCookieStore() {
            final StringBuilder cookies = new StringBuilder();
            for (final okhttp3.Cookie cookie : allCookies.values()) {
                cookies.append(cookie.name());
                cookies.append('=');
                cookies.append(cookie.value());
                cookies.append('=');
                cookies.append(cookie.domain());
                cookies.append(';');
            }
            return cookies.toString();
        }
    }

    private Cookies() {
        // Utility class
    }

    public static void restoreCookieStore(final String oldCookies) {
        cookieJar.restoreCookieStore(oldCookies);
    }

    public static String dumpCookieStore() {
        return cookieJar.dumpCookieStore();
    }

    public static void clearCookies() {
        cookieJar.clear();
    }
}

@@ -38,167 +38,16 @@
 ort 
-ch.boye.httpclientandroidlib.client.CookieStore;%0Aimport ch.boye.httpclientandroidlib.cookie.Cookie;%0Aimport ch.boye.httpclientandroidlib.impl.cookie.BasicClient
+okhttp3.
 Cook
@@ -181,59 +181,8 @@
 s;%0A%0A
-import java.util.ArrayList;%0Aimport java.util.Date;%0A
 impo
@@ -361,1619 +361,8 @@
 r();
-%0A    final static CookieStore cookieStore = new CompatibilityCookieStore(cookieJar);%0A%0A    static class CompatibilityCookieStore implements CookieStore %7B%0A%0A        private final InMemoryCookieJar cookieJar;%0A%0A        CompatibilityCookieStore(final InMemoryCookieJar cookieJar) %7B%0A            this.cookieJar = cookieJar;%0A        %7D%0A%0A        @Override%0A        public void addCookie(final Cookie cookie) %7B%0A            final String domain = cookie.getDomain();%0A            final okhttp3.Cookie newCookie = new Builder()%0A                    .domain(domain.startsWith(%22.%22) ? domain.substring(1) : domain)%0A                    .name(cookie.getName())%0A                    .value(cookie.getValue())%0A                    .build();%0A            cookieJar.addCookie(newCookie);%0A        %7D%0A%0A        @Override%0A        public List%3CCookie%3E getCookies() %7B%0A            final List%3Cokhttp3.Cookie%3E allCookies;%0A            synchronized (cookieJar) %7B%0A                allCookies = new ArrayList%3C%3E(cookieJar.allCookies.values());%0A            %7D%0A            final List%3CCookie%3E cookies = new ArrayList%3C%3E(allCookies.size());%0A            for (final okhttp3.Cookie cookie: allCookies) %7B%0A                final BasicClientCookie newCookie = new BasicClientCookie(cookie.name(), cookie.value());%0A                newCookie.setDomain('.' + cookie.domain());%0A                cookies.add(newCookie);%0A            %7D%0A            return cookies;%0A        %7D%0A%0A        @Override%0A        public boolean clearExpired(final Date date) %7B%0A            return false;%0A        %7D%0A%0A        @Override%0A        public void clear() %7B%0A            cookieJar.clear();%0A        %7D%0A    %7D
 %0A%0A  
@@ -448,24 +448,16 @@
 String, 
-okhttp3.
 Cookie%3E 
@@ -634,32 +634,24 @@
  final List%3C
-okhttp3.
 Cookie%3E cook
@@ -676,32 +676,24 @@
  for (final 
-okhttp3.
 Cookie cooki
@@ -800,32 +800,24 @@
 ookie(final 
-okhttp3.
 Cookie cooki
@@ -977,32 +977,24 @@
 public List%3C
-okhttp3.
 Cookie%3E load
@@ -1048,24 +1048,16 @@
 al List%3C
-okhttp3.
 Cookie%3E 
@@ -1142,32 +1142,24 @@
  for (final 
-okhttp3.
 Cookie cooki
@@ -2361,24 +2361,16 @@
  (final 
-okhttp3.
 Cookie c

Remove compatibility mode for cookies