package com.atlassian.confluence.rpc.soap.services;

import com.atlassian.confluence.rpc.soap.AbstractSoapTestCase;
import com.atlassian.confluence.rpc.RemoteException;
import com.atlassian.confluence.importexport.ImportExportManager;
import com.atlassian.confluence.importexport.ExportContext;
import com.atlassian.confluence.importexport.DefaultExportContext;
import com.atlassian.confluence.user.UserAccessor;
import com.atlassian.confluence.user.DefaultUserAccessor;
import com.atlassian.confluence.user.AuthenticatedUserThreadLocal;
import com.atlassian.confluence.security.GateKeeper;
import com.atlassian.confluence.setup.BootstrapManager;
import com.atlassian.confluence.event.EventManager;
import com.atlassian.confluence.event.EventListener;
import com.atlassian.confluence.event.events.ConfluenceEvent;
import com.atlassian.user.User;
import com.atlassian.user.Group;
import com.mockobjects.dynamic.C;
import com.mockobjects.dynamic.Mock;
import com.mockobjects.dynamic.ConstraintMatcher;
import com.mockobjects.constraint.Constraint;


public class TestAdminSoapService extends AbstractSoapTestCase
{
    public static final String DOMAIN_PREFIX = "http://yourorg.org";

    EventManager eventManager;

    AdminSoapService service = new AdminSoapService();
    Mock bootstrapManager = new Mock(BootstrapManager.class);

    GateKeeper gateKeeper = new GateKeeper(){
        public void addKey(String path, User user)
        {
        }

        public boolean isAccessPermitted(String path, User user)
        {
            return true;  //To change body of implemented methods use File | Settings | File Templates.
        }

        public void cleanAllKeys()
        {
        }

        public void allowAnonymousAccess(String path)
        {

        }
    };

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

        eventManager = new EventManager(){
            public void publishEvent(ConfluenceEvent event)
            {
            }

            public void registerListener(String listenerKey, EventListener listener)
            {
            }

            public void unregisterListener(String listenerKey)
            {
            }
        };
        service.setImportExportManager((ImportExportManager) mockImportExportManager.proxy());
        service.setGateKeeper(gateKeeper);
        service.setBootstrapManager((BootstrapManager) mockBootstrapManager.proxy());

        ((DefaultUserAccessor) userAccessor).setEventManager(eventManager);
    }

    public void tearDown() throws Exception
    {
        super.tearDown();
    }


    public void testExportSiteWithValidAdminWithoutAttachments()
    {
        mockBootstrapManager.expectAndReturn("getBaseUrl", DOMAIN_PREFIX);

        userToConfluenceAdmin();

        // Make the user the active user
        AuthenticatedUserThreadLocal.setUser(user);

        ExportContext ctx = new DefaultExportContext(ImportExportManager.EXPORT_XML_TYPE_ALL);

        ConstraintMatcher args = new ConstraintMatcher()
        {
            public boolean matches(Object[] objects)
            {
                try
                {
                    return ! ((Boolean) objects[0]).booleanValue() &&
                        ! ((Boolean) objects[1]).booleanValue() &&
                        ! ((Boolean) objects[2]).booleanValue() &&
                        ImportExportManager.EXPORT_XML_TYPE_ALL.equals(objects[3]);
                }
                catch (Exception e)
                {
                    return false;
                }
            }

            public Object[] getConstraints()
            {
                return new Object[0];
            }
        };

        mockImportExportManager.expectAndReturn("buildExportContext", args, ctx);
        mockImportExportManager.expectAndReturn("exportAs", C.args(C.eq(ImportExportManager.TYPE_ALL_DATA), C.IS_ANYTHING ), "theArchive.zip" );
        mockImportExportManager.expectAndReturn("prepareDownloadPath", C.args(C.eq("theArchive.zip")) , "/downloads/theArchive.zip" );

        String downloadPath = null;
        try
        {
            downloadPath = service.exportSite(false);
        }
        catch (RemoteException e)
        {
            fail();
        }

        assertEquals(DOMAIN_PREFIX + "/downloads/theArchive.zip", downloadPath);
        mockImportExportManager.verify();
    }

    public void testExportSiteWithValidAdminWithAttachments()
    {
        userToConfluenceAdmin();

        // Make the user the active user
        AuthenticatedUserThreadLocal.setUser(user);

        ExportContext ctx = new DefaultExportContext(ImportExportManager.EXPORT_XML_TYPE_ALL);
        mockBootstrapManager.expectAndReturn("getBaseUrl", DOMAIN_PREFIX);

        ConstraintMatcher args = new ConstraintMatcher()
        {
            public boolean matches(Object[] objects)
            {
                try
                {
                    return ((Boolean) objects[0]).booleanValue() &&
                        ! ((Boolean) objects[1]).booleanValue() &&
                        ! ((Boolean) objects[2]).booleanValue() &&
                        ImportExportManager.EXPORT_XML_TYPE_ALL.equals(objects[3]);
                }
                catch (Exception e)
                {
                    return false;
                }
            }

            public Object[] getConstraints()
            {
                return new Object[0];
            }
        };

        mockImportExportManager.expectAndReturn("buildExportContext", args, ctx);
        mockImportExportManager.expectAndReturn("exportAs", C.args(C.eq(ImportExportManager.TYPE_ALL_DATA), C.IS_ANYTHING ), "theArchive.zip" );
        mockImportExportManager.expectAndReturn("prepareDownloadPath", C.args(C.eq("theArchive.zip")) , "/downloads/theArchive.zip" );

        String downloadPath = null;
        try
        {
            downloadPath = service.exportSite(true);
        }
        catch (RemoteException e)
        {
            fail();
        }

        assertEquals(DOMAIN_PREFIX + "/downloads/theArchive.zip", downloadPath);
        mockImportExportManager.verify();
    }

    public void testExportSiteWithInvalidAdmin()
     {
         String downloadPath = null;

         try
         {
             downloadPath = service.exportSite(true);
             fail();
         }
         catch (RemoteException e)
         {
         }

         assertEquals(null, downloadPath);
     }


    private void userToConfluenceAdmin()
    {
        userAccessor.addGroup(UserAccessor.GROUP_CONFLUENCE_ADMINS);
        Group g = userAccessor.getGroup(UserAccessor.GROUP_CONFLUENCE_ADMINS);
        userAccessor.addMembership(g, user);
    }
}
