package ctbrec.sites.showup;

import static ctbrec.io.HttpConstants.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Objects;

import ctbrec.Config;
import ctbrec.Settings;
import ctbrec.io.HttpClient;
import ctbrec.io.HttpException;
import okhttp3.Cookie;
import okhttp3.FormBody;
import okhttp3.Request;
import okhttp3.Response;

public class ShowupHttpClient extends HttpClient {

    private static final Logger LOG = LoggerFactory.getLogger(ShowupHttpClient.class);
    private String csrfToken;

    protected ShowupHttpClient() {
        super("showup");
        setCookie("accept_rules", "true");
        setCookie("category", "all");
    }

    public void setCookie(String name, String value) {
        Cookie cookie = new Cookie.Builder()
                .domain("showup.tv")
                .name(name)
                .value(value)
                .build();

        Map<String, List<Cookie>> cookies = cookieJar.getCookies();
        List<Cookie> cookiesForDomain = cookies.computeIfAbsent(cookie.domain(), k -> new ArrayList<Cookie>());
        for (Iterator<Cookie> iterator = cookiesForDomain.iterator(); iterator.hasNext();) {
            Cookie existingCookie = iterator.next();
            if (Objects.equal(existingCookie.name(), cookie.name())) {
                iterator.remove();
            }
        }
        cookiesForDomain.add(cookie);
    }

    public String getCsrfToken() throws IOException {
        if (csrfToken == null) {
            Request req = new Request.Builder()
                    .url(Showup.BASE_URL + "/site/log_in")
                    .header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
                    .build();

            try (Response response = execute(req)) {
                if (response.isSuccessful()) {
                    String body = response.body().string();
                    Matcher m = Pattern.compile("var csrf = '(.*?)';").matcher(body);
                    if (m.matches()) {
                        csrfToken = m.group(1);
                    } else {
                        throw new RuntimeException("CSRF Token not found"); // NOSONAR
                    }
                } else {
                    throw new HttpException(response.code(), response.message());
                }
            }
        }
        return csrfToken;
    }

    @Override
    public boolean login() throws IOException {
        Settings settings = Config.getInstance().getSettings();
        FormBody body = new FormBody.Builder()
                .add("is_ajax", "1")
                .add("email", settings.showupUsername)
                .add("password", settings.showupPassword)
                .add("remember", "1")
                .build();
        Request req = new Request.Builder()
                .url(Showup.BASE_URL)
                .header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
                .header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
                .header(REFERER, Showup.BASE_URL + '/')
                .header(ORIGIN, Showup.BASE_URL)
                .header(ACCEPT, MIMETYPE_APPLICATION_JSON)
                .post(body)
                .build();

        try (Response response = execute(req)) {
            if (response.isSuccessful()) {
                String responseBody = response.body().string();
                if (responseBody.startsWith("{")) {
                    JSONObject json = new JSONObject(responseBody);
                    return json.optString("status").equalsIgnoreCase("success");
                } else {
                    return false;
                }
            } else {
                throw new HttpException(response.code(), response.message());
            }
        }
    }
}
