package pta.de.core.controller;

import org.eclipse.jetty.http.HttpStatus;
import org.junit.Test;
import org.powermock.reflect.Whitebox;
import pta.de.api.ServiceDistributionCluster;
import pta.de.core.common.util.ResourceLoaderBase;
import pta.de.core.exceptions.HttpStatusException;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;


public class BackendControllerTest {

    private ServiceDistributionCluster baseTestReadServerDistribution(String clustername, String jsonFile) throws Exception {
        ResourceLoaderBase resourceLoaderBase = new ResourceLoaderBase();
        String json = resourceLoaderBase.loadStringFromResource(jsonFile);

        ServicesConfigCache scc = ServicesConfigCache.getInstance();
        ServiceDistributionCluster[] sdc = (ServiceDistributionCluster[])
                Whitebox.invokeMethod(scc,"readServerDistributionFromText", json);

        Whitebox.setInternalState(scc, "cache", sdc);

        BackendController be = new BackendController();

        ServiceDistributionCluster ret = be.readServerDistribution(clustername);

        return ret;
    }

    @Test
    public void testReadServerDistribution() throws Exception {

        ServiceDistributionCluster sdc = baseTestReadServerDistribution("elogbook.openK", "testServiceDistributions.json");

        assertEquals(sdc.clustername, "elogbook.openK");
        assertEquals(sdc.getDistributions().length, 1);
        assertEquals(sdc.getDistributions()[0].host, "172.18.22.160");
    }

    @Test
    public void testFailReadServerDistribution() throws Exception {
        try {
            baseTestReadServerDistribution("doesntMatter", "testServiceDist_False.json");
        } catch( HttpStatusException e ) {
            assertEquals(e.getHttpStatus(), HttpStatus.INTERNAL_SERVER_ERROR_500);
        }
    }

    @Test
    public void testReadServerDistribution_notfound() throws Exception {
        try {
            ServiceDistributionCluster sdc = baseTestReadServerDistribution("invalidCluster", "testServiceDistributions.json");
        } catch( HttpStatusException e ) {
            assertEquals(e.getHttpStatus(), HttpStatus.NOT_FOUND_404);
        }
    }

    @Test
    public void testReadServerDistribution_activeInactive() throws Exception {
        ServiceDistributionCluster sdc = baseTestReadServerDistribution( "elogbook.openK", "testServiceDistributionsTwo_OneIsInactive.json");

        assertEquals( 1, sdc.getDistributions().length);
        assertTrue( sdc.getDistributions()[0].isActive());
        assertEquals( "172.18.22.160", sdc.getDistributions()[0].getHost());
    }
}
