package pta.de;

import com.codahale.metrics.health.HealthCheckRegistry;
import io.dropwizard.jersey.setup.JerseyEnvironment;
import io.dropwizard.jetty.setup.ServletEnvironment;
import io.dropwizard.setup.Environment;
import org.easymock.EasyMock;
import org.eclipse.jetty.servlets.CrossOriginFilter;
import org.junit.Test;
import org.powermock.reflect.Whitebox;

import javax.servlet.FilterRegistration;

import static org.easymock.EasyMock.*;
import static org.junit.Assert.assertEquals;
import static org.powermock.api.easymock.PowerMock.replay;

public class MicsCentralApplicationTest {

    @Test
    public void testGetName() {
        assertEquals( "micsCentral", new MicsCentralApplication().getName());
    }

    @Test
    public void testRun() {

        MicsCentralConfiguration conf = createConfiguration();
        MicsCentralApplication mca = new MicsCentralApplication();
        mca.run(conf, createMockedEnvironment());

    }

    @Test
    public void testRun2() throws Exception {
        MicsCentralApplication mca = new MicsCentralApplication();
        Whitebox.invokeMethod(mca, "configureCors", createMockedEnvironment() );
    }
    private MicsCentralConfiguration createConfiguration() {
        MicsCentralConfiguration c = new MicsCentralConfiguration();
        c.setServicesDistributionFileName("src/test/resources/testServiceDistributions.json");
        return c;
    }

    private Environment createMockedEnvironment() {
        FilterRegistration.Dynamic cors = EasyMock.createMock(FilterRegistration.Dynamic.class);
        expect(cors.setInitParameter(anyString(), anyString())).andReturn( Boolean.TRUE ).anyTimes();
        cors.addMappingForUrlPatterns(anyObject(), anyBoolean(), anyString());
        expectLastCall();
        replay( cors );

        ServletEnvironment se = EasyMock.createMock(ServletEnvironment.class);
        expect(se.addFilter(eq("CORS"), eq(CrossOriginFilter.class))).andReturn(cors).anyTimes();
        replay(se);

        JerseyEnvironment je = EasyMock.createMock(JerseyEnvironment.class);
        je.register(anyObject());
        expectLastCall();

        HealthCheckRegistry hcr = EasyMock.createMock(HealthCheckRegistry.class);
        hcr.register(anyString(), anyObject());
        expectLastCall();

        Environment environment = EasyMock.createMock( Environment.class );
        expect( environment.servlets() ).andReturn(se).anyTimes();
        expect( environment.jersey() ).andReturn(je).anyTimes();
        expect( environment.healthChecks() ).andReturn(hcr).anyTimes();
        replay( environment );
        verify( environment );
        return environment;
    }
}
