package ctbrec.sites.stripchat;

import static ctbrec.io.HttpConstants.*;

import java.io.IOException;

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

import ctbrec.Config;
import ctbrec.io.HttpClient;
import ctbrec.io.HttpException;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class StripchatHttpClient extends HttpClient {

    private static final Logger LOG = LoggerFactory.getLogger(StripchatHttpClient.class);

    private long userId;
    private String csrfToken;
    private String csrfTimestamp;
    private String csrfNotifyTimestamp;

    public StripchatHttpClient() {
        super("stripchat");
    }

    @Override
    public boolean login() throws IOException {
        if(loggedIn) {
            return true;
        }

        // persisted cookies might let us log in
        if(checkLoginSuccess()) {
            loggedIn = true;
            LOG.debug("Logged in with cookies");
            return true;
        }

        if (csrfToken == null) {
            loadCsrfToken();
        }

        String url = Stripchat.BASE_URI + "/api/front/auth/login";
        JSONObject requestParams = new JSONObject();
        requestParams.put("loginOrEmail", Config.getInstance().getSettings().stripchatUsername);
        requestParams.put("password", Config.getInstance().getSettings().stripchatPassword);
        requestParams.put("remember", true);
        requestParams.put("csrfToken", csrfToken);
        requestParams.put("csrfTimestamp", csrfTimestamp);
        requestParams.put("csrfNotifyTimestamp", csrfNotifyTimestamp);
        RequestBody body = RequestBody.create(MediaType.parse("application/json"), requestParams.toString());
        Request request = new Request.Builder()
                .url(url)
                .header(ACCEPT, MIMETYPE_APPLICATION_JSON)
                .header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
                .header(ORIGIN, Stripchat.BASE_URI)
                .header(REFERER, Stripchat.BASE_URI)
                .header(CONTENT_TYPE, MIMETYPE_APPLICATION_JSON)
                .post(body)
                .build();
        try (Response response = execute(request)) {
            if (response.isSuccessful()) {
                JSONObject resp = new JSONObject(response.body().string());
                if(resp.has("user")) {
                    JSONObject user = resp.getJSONObject("user");
                    userId = user.optLong("id");
                    return true;
                } else {
                    return false;
                }
            } else {
                throw new HttpException(response.code(), response.message());
            }
        }
    }

    private void loadCsrfToken() throws IOException {
        String url = Stripchat.BASE_URI + "/api/front/v2/config/data?requestPath=%2F&timezoneOffset=0";
        Request request = new Request.Builder()
                .url(url)
                .header(ACCEPT, MIMETYPE_APPLICATION_JSON)
                .header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
                .header(ORIGIN, Stripchat.BASE_URI)
                .header(REFERER, Stripchat.BASE_URI)
                .header(CONTENT_TYPE, MIMETYPE_APPLICATION_JSON)
                .build();
        try (Response response = execute(request)) {
            if (response.isSuccessful()) {
                JSONObject resp = new JSONObject(response.body().string());
                JSONObject data = resp.getJSONObject("data");
                csrfToken = data.optString("csrfToken");
                csrfTimestamp = data.optString("csrfTimestamp");
                csrfNotifyTimestamp = data.optString("csrfNotifyTimestamp");
            } else {
                throw new HttpException(response.code(), response.message());
            }
        }
    }

    /**
     *  check, if the login worked
     * @throws IOException
     */
    public boolean checkLoginSuccess() {
        return userId > 0;
    }

    public long getUserId() {
        return userId;
    }

    public String getCsrfNotifyTimestamp() {
        return csrfNotifyTimestamp;
    }

    public String getCsrfTimestamp() {
        return csrfTimestamp;
    }

    public String getCsrfToken() {
        return csrfToken;
    }
}
