package cz.moneta.test.harness.endpoints.ods;

import cz.moneta.test.harness.connectors.database.OracleConnector;
import cz.moneta.test.harness.context.StoreAccessor;
import cz.moneta.test.harness.endpoints.Endpoint;
import cz.moneta.test.harness.support.auth.AuthSupport;
import cz.moneta.test.harness.support.auth.Credentials;
import org.jooq.Record;
import org.jooq.Result;

import java.math.BigInteger;
import java.util.Optional;

public class OdsEndpoint implements Endpoint {

    private final StoreAccessor store;
    private final ThreadLocal<OracleConnector> connector = ThreadLocal.withInitial(this::initConnector);

    public OdsEndpoint(StoreAccessor store) {
        this.store = store;
    }

    public Result<Record> executeSql(String sql) {
        return connector.get().executeSql(sql);
    }

    @Override
    public boolean canAccess() {
        return AuthSupport.hasCredentials("ods", store);
    }

    private OracleConnector initConnector() {
        String endpointName = "endpoints.ods.url";
        Credentials credentials = AuthSupport.getCredentials("ods", store);
        return Optional.ofNullable(store.getConfig(endpointName))
                .map(url -> new OracleConnector(url, credentials.getUsername(), credentials.getPassword()))
                .orElseThrow(() -> new IllegalStateException("You need to configure " + endpointName + " to work with ODS"));
    }

    public long getUniPtKey(String rc, String ico) {
        String sql = "select distinct up.uni_pt_key " +
                "  from ODS_L1_OWNER.inst_pt ip " +
                "  left join ODS_L1_OWNER.uni_pt up " +
                "    on ip.uni_pt_key = up.uni_pt_key " +
                " where up.bus_key = 1 " +
                "   and up.uni_pt_key > 0 " +
                "   and up.del_flag = 0 ";

        if (rc != null && !rc.equals("")) {
            sql += " and up.rc_num = '" + rc + "' ";
        }

        if (ico != null && !ico.equals("")) {
            sql += " and up.ico_num = '" + ico + "' ";
        } else {
            sql += " and up.pt_tp_key = 1";
        }

        Result<Record> result = executeSql(sql);

        if (result.size() > 1) {
            throw new IllegalStateException("More than one uniPtKey found! (Input RC: " + rc + " ICO: " + ico + ")");
        }
        if (result.size() < 1) {
            throw new IllegalStateException("No uniPtKey found! (Input RC: " + rc + " ICO: " + ico + ")");
        }

        return ((BigInteger) result.getValue(0, 0)).longValue();
    }

    public boolean checkScoreCardId(String scId) {
        String sql = "select * from ODS_L1_OWNER.Scg_Tp stp where stp.del_flag=0 and stp.id = '" + scId + "'";
        return executeSql(sql).size() == 1 ? true : false;
    }

    public String checkSegmentCodeAndGetId(String segmentCode, String segmentationCode) {
        String sql = "select segm.segm_key from ODS_L1_OWNER.seg seg join ODS_L1_OWNER.segm segm on seg.segm_key=segm.segm_key where segm.id = '" + segmentCode + "' and seg.id = '" + segmentationCode + "'";
        return executeSql(sql).stream()
                .findFirst()
                .map(x -> x.getValue(0).toString())
                .orElse(null);
    }
}
