package cz.moneta.test.sanity.transactional;

import cz.moneta.test.dsl.Harness;
import cz.moneta.test.dsl.wso2.data.CardData;
import cz.moneta.test.harness.connectors.VaultConnector;
import cz.moneta.test.harness.endpoints.jira.JiraEndpoint;
import cz.moneta.test.harness.support.rest.RawRestRequest;
import cz.moneta.test.harness.support.util.Level;

import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class SmokeData {
    private static SmokeData INSTANCE;
    private final Harness harness;
    private final CardData creditClient;
    private final CardData debitClient;
    private final Properties smokeTestsConfig;
    private final boolean isGW;
    private final Properties gwPaths = new Properties();
    private final Properties eiPaths = new Properties();
    private final Map<String, String> environmentConfig = new HashMap<>();

    private SmokeData(Harness harness) {
        this.harness = harness;
        environmentConfig.put("fve", "FVP-T4262");
        environmentConfig.put("ppe", "FVP-T2850");
        environmentConfig.put("tst3", "FVP-T6566");
        smokeTestsConfig = getDataFromJiraTestPrecondition();
        isGW = Boolean.valueOf(smokeTestsConfig.getProperty("Wso2GW"));
        creditClient = harness.tasks().wso2().cards().getCardInfoByRc(smokeTestsConfig.getProperty("creditRc"), "C");
        debitClient = harness.tasks().wso2().cards().getCardInfoByRc(smokeTestsConfig.getProperty("debitRc"), "D");
        harness.log(Level.INFO, "Credit client " + creditClient);
        harness.log(Level.INFO, "Debit client " + debitClient);

        try {
            gwPaths.load(getClass().getClassLoader().getResourceAsStream("regression/transactional/cards/sme/Wso2GwPaths"));
            eiPaths.load(getClass().getClassLoader().getResourceAsStream("regression/transactional/cards/sme/Wso2EIPaths"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static SmokeData getInstance(Harness harness) {
        synchronized (SmokeData.class) {
            if (INSTANCE == null) {
                synchronized (SmokeData.class) {
                    INSTANCE = new SmokeData(harness);
                }
            }
            return INSTANCE;
        }
    }

    private static String getAccessToken(Harness store) {
        VaultConnector v = new VaultConnector(store.getConfig("vault.url"), store.getConfig("vault.username"), store.getConfig("vault.password"));
        return (String) v.getValue("/kv/autotesty/common/jira", "token")
                .orElse(store.getConfig("reports.tmfj.token"));
    }

    private JiraEndpoint getJiraEndpoint() {
        return new JiraEndpoint(harness.getConfig("reports.tmfj.url"));
    }

    public CardData getCreditData() {
        return creditClient;
    }

    public CardData getDebitData() {
        return debitClient;
    }

    private Properties getDataFromJiraTestPrecondition() {
        String comment = RawRestRequest.jsonBuilder(getJiraEndpoint())
                .withPath("testcase/" + environmentConfig.get(harness.getConfig("environment.type")))
                .withHeader("Authorization", "Basic " + getAccessToken(harness))
                .get().extract("precondition").textValue()
                .replaceAll("<.{1,4}>", "\n");
        Properties result = new Properties();
        try {
            result.load(new StringReader(comment));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    public String getPath(String apiId) {
        return "/t/cards.cluster/" + (isGW ? gwPaths.getProperty(apiId) : eiPaths.getProperty(apiId));
    }

    public boolean isGw() {
        return isGW;
    }

    public String getAccountWithStatements() {
        return smokeTestsConfig.getProperty("accountWithStatements");
    }

    public String getCardForRenew() {
        return smokeTestsConfig.getProperty("cardForRenewal");
    }

    public String getStudentBU() {
        return smokeTestsConfig.getProperty("studentBU");
    }

    public String getLostAccount() {
        return smokeTestsConfig.getProperty("lostAccount");
    }

    public String getTransferAccount() {
        return smokeTestsConfig.getProperty("transferAccount");
    }

}
