package cz.moneta.test.dsl.salesforceapi.tasks;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import cz.moneta.test.dsl.Harness;
import cz.moneta.test.dsl.util.credentials.Keys;
import cz.moneta.test.harness.support.auth.AuthSupport;
import cz.moneta.test.harness.support.auth.Credentials;
import cz.moneta.test.harness.support.rest.RawRestRequest;
import org.junit.jupiter.api.Assertions;

public class SalesForceApiTasks {
    private final Harness harness;

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

    public String getAuthorizationToken() {
        Credentials credsUser = AuthSupport.getCredentials(Keys.salesForce.banker, harness);
        Credentials credsId = AuthSupport.getCredentials(Keys.salesForce.clientId, harness);
        Credentials credsSecret = AuthSupport.getCredentials(Keys.salesForce.clientSecret, harness);
        String requestBody = "grant_type=password" +
                "&client_id=" + credsId.getPassword() +
                "&client_secret=" + credsSecret.getPassword() +
                "&username=" + credsUser.getUsername().replace("@", "%40") +
                "&password=" + credsUser.getPassword();

        RawRestRequest.Response response = harness.withSalesForceApi()
                .prepareRequestUrlEncoded()
                .withPath("/oauth2/token")
                .withHeader("cache-control", "no-cache")
                .withHeader("content-type", "application/x-www-form-urlencoded")
                .withPayload(requestBody)
                .post()
                .andAssertStatus(200)
                .andAssertPresent("access_token");
        return response.extract("access_token").asText();
    }

    public String getLatestApiVersion() {
        RawRestRequest.Response response = harness.withSalesForceApi()
                .prepareRequest()
                .withPath("/data")
                .get()
                .andAssertStatus(200);
        ArrayNode nodeList = (ArrayNode) response.extract("");
        Assertions.assertNotEquals(nodeList.size(), 0);
        JsonNode lastNode = nodeList.get(nodeList.size() - 1);
        return lastNode.findValue("version").asText();
    }

    public void lockAccount(String account) {
        String token = harness.tasks().salesForceApiTasks().getAuthorizationToken();
        String ownerId = harness.getConfig("salesforce.test.testAutomationUserId");

        harness.withSalesForceApi()
                .prepareRequest()
                .withPath(String.format("/data/v51.0/sobjects/Account/%s", account))
                .withHeader("Authorization", "Bearer " + token)
                .withPayloadPatch(String.format("{\"locked__c\": \"Ano\", \"OwnerId\": \"%s\"}", ownerId))
                .patch()
                .andAssertStatus(204);
    }

    public void unlockAccount(String account) {
        String token = harness.tasks().salesForceApiTasks().getAuthorizationToken();
        String ownerId = harness.getConfig("salesforce.test.systemUserId");

        harness.withSalesForceApi()
                .prepareRequest()
                .withPath(String.format("/data/v51.0/sobjects/Account/%s", account))
                .withHeader("Authorization", "Bearer " + token)
                .withPayloadPatch(String.format("{\"locked__c\": \"Ne\", \"OwnerId\": \"%s\"}", ownerId))
                .patch()
                .andAssertStatus(204);
    }
}
