package com.nasageek.utexasutilities;

import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;

import com.squareup.okhttp.FormEncodingBuilder;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;

import java.io.IOException;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookieStore;
import java.net.HttpCookie;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.List;

/**
 * Created by Chris on 7/4/2014.
 */
public class AuthCookie {

    protected String prefKey;
    protected String authCookie;
    protected String authCookieKey;
    protected String userNameKey;
    protected String passwordKey;
    protected boolean cookieHasBeenSet;
    protected OkHttpClient client;
    protected SharedPreferences settings;
    protected SecurePreferences secureSettings;
    protected URL url;


    public AuthCookie(String prefKey, String authCookieKey, String loginUrl, String userNameKey,
                      String passwordKey, Context con) {
        this.prefKey = prefKey;
        this.authCookieKey = authCookieKey;
        this.userNameKey = userNameKey;
        this.passwordKey = passwordKey;
        try {
            this.url = new URL(loginUrl);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        this.client = new OkHttpClient();
        this.secureSettings = new SecurePreferences(con, "com.nasageek.utexasutilities.password",
                false);
        this.settings = PreferenceManager.getDefaultSharedPreferences(con);
    }

    public boolean hasCookieBeenSet() {
        return cookieHasBeenSet;
    }

    public String getPrefKey() {
        return prefKey;
    }

    public String getAuthCookieVal() {
        if (cookieHasBeenSet) {
            return authCookie;
        } else if (settings.contains(prefKey)) {
            cookieHasBeenSet = true;
            authCookie = settings.getString(prefKey, "");
            return authCookie;
        } else {
            try {
                login();
            } catch (IOException ie) {
                ie.printStackTrace();
            }
            return authCookie;
        }
    }

    private void resetCookie() {
        Utility.commit(settings.edit().remove(prefKey));
        authCookie = "";
        try {
            /*
            This step is *required* for PNA, and nicety for other services. PNA won't let you
            log in if you're still holding on to a valid authcookie, so we clear them out.
             */
            URI loginURI = URI.create(url.getHost());
            CookieStore cookies = ((CookieManager) CookieHandler.getDefault()).getCookieStore();
            for (HttpCookie cookie : cookies.get(loginURI)) {
                cookies.remove(loginURI, cookie);
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }
        cookieHasBeenSet = false;
    }

    public void setAuthCookieVal(String authCookie) {
        this.authCookie = authCookie;
        Utility.commit(settings.edit().putString(prefKey, authCookie));

        /*
        this is technically unnecessary if OkHttp handled the authentication, because it will
        have already set the cookies in the CookieHandler. It doesn't seem to cause any issues
        just to re-add the cookies, though
         */
        HttpCookie httpCookie = new HttpCookie(authCookieKey, authCookie);
        httpCookie.setDomain(url.getHost());
        // this is required for PNA login and does not appear to affect other services
        httpCookie.setVersion(0);
        try {
            CookieStore cookies = ((CookieManager) CookieHandler.getDefault()).getCookieStore();
            cookies.add(URI.create(url.getHost()), httpCookie);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }
        cookieHasBeenSet = true;
    }

    public void login() throws IOException {
        Request request = buildLoginRequest();
        performLogin(request);
    }

    protected void performLogin(Request request) throws IOException {
        Response response = client.newCall(request).execute();
        if (!response.isSuccessful()) {
            throw new IOException("Bad response code " + response);
        }
        CookieManager cm = (CookieManager) CookieHandler.getDefault();
        List<HttpCookie> cookies = cm.getCookieStore().getCookies();
        for (HttpCookie cookie : cookies) {
            // special case for UTD login since I'm too lazy to subclass it
            String cookieVal = cookie.getValue();
            if (cookie.getName().equals(authCookieKey) && !cookieVal.equals("NONE")) {
                setAuthCookieVal(cookieVal);
                return;
            }
        }
        // do something otherwise
    }

    protected Request buildLoginRequest() {
        String user = settings.getString("eid", "error");
        String pw = secureSettings.getString("password");

        RequestBody requestBody = new FormEncodingBuilder()
                .add(userNameKey, user)
                .add(passwordKey, pw)
                .build();
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        return request;
    }

    public void logout() {
        resetCookie();
    }
}

@@ -2185,160 +2185,19 @@
     
- try %7B%0A                login();%0A            %7D catch (IOException ie) %7B%0A                ie.printStackTrace();%0A            %7D%0A            return authCookie
+return null
 ;%0A  

Disable automatically logging in in certain cases when getCookieVal is called in AuthCookie. While it is conceptually neat (lazy login!), I don't think this auto-login almost ever happened, and it began to cause issues when temp login was activated that I felt warranted the change.