package cz.moneta.test.dsl.util.task.ib;

import cz.moneta.test.dsl.Harness;
import cz.moneta.test.harness.support.rest.RawRestRequest;
import cz.moneta.test.harness.support.auth.Credentials;

public class IbLoginApiTasks {

    private final Harness harness;

    String DEFAULT_CLIENT_PASSWORD_TOKEN = "5c05d25b14799ac1cfbc8a5f45109855e9fd5dd50ff910144f480371978413cb9da91446e524be1aab3a7bcdcc5a76552945596f7a065fdfb9be4610a062a9e0";
    String DEFAULT_MOBILE_KEY = "12341234";
    String NEW_PASSWORD = "Test1234";
    String DEFAULT_PASSWORD = "Aa123456";

    public IbLoginApiTasks(Harness harness) {
        this.harness = harness;
    }

    public Credentials loginAndConfirmAuthWithSms(String username) {
        String cookie = getSessionCookie(username);

        boolean isPasswordChangeRequired = prepareRequestWithHeaders("session/ib/login/commit")
                .withHeader("Cookie", cookie)
                .withPayload("{\"mobileKey\": \"" + DEFAULT_MOBILE_KEY + "\"}")
                .post()
                .extract("responseObject.passwordChange")
                .asBoolean();

        if (isPasswordChangeRequired) {
            changePassword(cookie);
            confirmAuthWithSms(cookie);
            return harness.tasks().wso2().idm().resetIbUserPasswordByUsername(username); //reset password back to default
        }

        confirmAuthWithSms(cookie);
        return new Credentials(username, DEFAULT_PASSWORD);
    }

    private String getSessionCookie(String username) {
        RawRestRequest.Response loginResponse = prepareRequestWithHeaders("session/ib/login-and-send")
                .withPayload("{\n" +
                        "    \"credentials\":\n" +
                        "    {\n" +
                        "        \"username\": \"" + username + "\",\n" +
                        "        \"authenticationToken\": \"" + DEFAULT_CLIENT_PASSWORD_TOKEN + "\"\n" +
                        "    }\n" +
                        "}")
                .postExtended();

        return loginResponse
                .getHeader("Set-Cookie")
                .stream()
                .filter(x -> x.toString()
                        .contains("SESSION"))
                .toList()
                .get(0)
                .toString();
    }

    private void changePassword(String cookie) {
        prepareRequestWithHeaders("session/ib/password/change-and-send")
                .withHeader("Cookie", cookie)
                .withPayload("{\"form\":{\"password\":{\"value\": \"" + NEW_PASSWORD + "\"}}}")
                .post();

        prepareRequestWithHeaders("session/ib/password/commit")
                .withHeader("Cookie", cookie)
                .withPayload("{\n" +
                        "    \"password\": \"" + NEW_PASSWORD + "\",\n" +
                        "    \"mobileKey\": \"" + DEFAULT_MOBILE_KEY + "\"\n" +
                        "}")
                .post();
    }

    private void confirmAuthWithSms(String cookie) {
        prepareRequestWithHeaders("secured/ib/retain-auth-sms/send-verification-message")
                .withHeader("Cookie", cookie)
                .withPayload("{}")
                .post().andAssertStatus(200);

        prepareRequestWithHeaders("/secured/ib/retain-auth-sms/consent-commit")
                .withHeader("Cookie", cookie)
                .withPayload("{\"mobileKey\": \"" + DEFAULT_MOBILE_KEY + "\"}")
                .post().andAssertStatus(200);
    }

    private RawRestRequest.Request prepareRequestWithHeaders(String path) {
        return harness.withOpenApi()
                .prepareRequest()
                .withPath(path)
                .withHeader("Content-Type", "application/json;charset=UTF-8")
                .withHeader("Channel", "15");
    }
}