package gov.va.med.edp.web.controller;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.AbstractResource;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.dao.DataAccessException;
import org.easymock.MockControl;

import gov.va.med.edp.dao.ServerPackageVersionDao;
import gov.va.med.edp.dao.SiteCodeLookUpDao;
import gov.va.med.edp.dao.TrackingDao;

import java.io.InputStream;
import java.io.IOException;

/**
 * TODO: document ClientVersionSynchronizationControllerTest
 */
public class ClientVersionSynchronizationControllerTest extends AbstractControllerTest {
    private MockControl mockLoaderControl;
    private ClientVersionSynchronizationController c;
    private ResourceLoader mockLoader;

    protected void setUp() throws Exception {
        super.setUp();

        mockLoaderControl = MockControl.createControl(ResourceLoader.class);
        mockLoader = (ResourceLoader) mockLoaderControl.getMock();
        webAppContext.setResourceLoader(mockLoader);
        
        MockControl siteDaoControl = MockControl.createControl(SiteCodeLookUpDao.class);
        SiteCodeLookUpDao siteCodeDao = (SiteCodeLookUpDao) siteDaoControl.getMock();

        MockControl trackingDaoControl = MockControl.createControl(TrackingDao.class);
        TrackingDao trackingDao = (TrackingDao) trackingDaoControl.getMock();
        
        
        c = new ClientVersionSynchronizationController();
        c.setApplicationContext(webAppContext);
        c.setClientArtifactId("foo-bar");
        c.setViewName("fooBarView");
        c.setIncompatibilityViewName("fooBarIncompatibleView");
        c.setTrackingDao(trackingDao);
        c.setSiteCodeDao(siteCodeDao);
        c.afterPropertiesSet();
    }

    public void testDefaultIncompatibilityViewName() {
        c = new ClientVersionSynchronizationController();
        assertEquals(ClientVersionSynchronizationController.DEFAULT_INCOMPATIBILITY_VIEW, c.getIncompatibilityViewName());
    }

    public void testNoServerPackageVersionOrServerErrorSessionAttribute() throws Exception {
        try {
            c.handleRequest(request, response);
            fail("expected illegal state exception");
        } catch (IllegalStateException e) {
            assertTrue(true);
        }
    }

    public void testNoServerPackageVersionSessionButServerErrorAttribute() throws Exception {
        DataAccessException ex = new DataAccessResourceFailureException("unable to fetch the thing and the thing and the hey lady!");

        session.setAttribute(SessionConstants.SERVER_ERROR_KEY, ex);

        try {
            c.handleRequest(request, response);
            fail("expected data access exception");
        } catch (DataAccessException e) {
            assertSame(ex, e);
        }
    }

    public void testViewReturnedWhenServerVersionMatchesCompatibleVersion() throws Exception {
        session.setAttribute(SessionConstants.SERVER_PACKAGE_VERSION_KEY, "1.0-T15-SNAPSHOT");

        mockLoaderControl.expectAndReturn(mockLoader.getResource("foo-bar-1.0-T15-SNAPSHOT.swf"), new MockResource(true));
        mockLoaderControl.replay();

        ModelAndView mav = c.handleRequest(request, response);
        assertEquals("fooBarView", mav.getViewName());
        assertEquals("1.0-T15-SNAPSHOT", mav.getModel().get("serverPackageVersion"));
        assertEquals("foo-bar", mav.getModel().get("clientArtifactId"));
        assertEquals("foo-bar-1.0-T15-SNAPSHOT", mav.getModel().get("clientFinalName"));

        mockLoaderControl.verify();
    }

    public void testViewReturnedWhenServerVersionIsIncompatible() throws Exception {
        session.setAttribute(SessionConstants.SERVER_PACKAGE_VERSION_KEY, "1.0-T15-SNAPSHOT");

        mockLoaderControl.expectAndReturn(mockLoader.getResource("foo-bar-1.0-T15-SNAPSHOT.swf"), new MockResource(false));
        mockLoaderControl.replay();

        ModelAndView mav = c.handleRequest(request, response);
        assertEquals("fooBarIncompatibleView", mav.getViewName());
        assertEquals("1.0-T15-SNAPSHOT", mav.getModel().get("serverPackageVersion"));
        assertEquals("foo-bar", mav.getModel().get("clientArtifactId"));
        assertEquals("foo-bar-1.0-T15-SNAPSHOT", mav.getModel().get("clientFinalName"));

        mockLoaderControl.verify();
    }

    static class MockResource extends AbstractResource {
        private boolean exists;

        public MockResource(boolean exists) {
            this.exists = exists;
        }

        public boolean exists() {
            return exists;
        }

        public String getDescription() {
            return null;
        }

        public InputStream getInputStream() throws IOException {
            return null;
        }
    }
}
