package org.apache.maven.archiva.webdav;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import java.io.File;
import org.apache.commons.io.FileUtils;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.DavResource;
import org.apache.jackrabbit.webdav.DavServletResponse;
import org.apache.jackrabbit.webdav.DavSession;
import org.apache.jackrabbit.webdav.lock.ActiveLock;
import org.apache.jackrabbit.webdav.lock.LockInfo;
import org.apache.jackrabbit.webdav.lock.LockManager;
import org.apache.jackrabbit.webdav.lock.Scope;
import org.apache.jackrabbit.webdav.lock.SimpleLockManager;
import org.apache.jackrabbit.webdav.lock.Type;
import org.apache.maven.archiva.webdav.util.MimeTypes;
import org.codehaus.plexus.spring.PlexusInSpringTestCase;
import org.codehaus.plexus.spring.PlexusToSpringUtils;

public class DavResourceTest extends PlexusInSpringTestCase
{
    private DavSession session;
    
    private MimeTypes mimeTypes;
    
    private ArchivaDavResourceLocator resourceLocator;
    
    private ArchivaDavResourceFactory factory;
    
    private File baseDir;
    
    private final String REPOPATH = "/myresource.jar";
    
    private final File myResource = new File(baseDir, REPOPATH);
    
    private DavResource resource;
    
    private LockManager lockManager;
    
    @Override
    protected void setUp()
        throws Exception
    {
        super.setUp();
        session = new ArchivaDavSession();
        mimeTypes = (MimeTypes)getApplicationContext().getBean(PlexusToSpringUtils.buildSpringId(MimeTypes.class));
        baseDir = new File("target/DavResourceTest");
        baseDir.mkdirs();
        myResource.createNewFile();
        resourceLocator = (ArchivaDavResourceLocator)new ArchivaDavLocatorFactory().createResourceLocator("/", REPOPATH);
        resource = getDavResource(REPOPATH, myResource);
        lockManager = new SimpleLockManager();
        resource.addLockManager(lockManager);
    }

    @Override
    protected void tearDown()
        throws Exception
    {
        super.tearDown();
        release(mimeTypes);
        FileUtils.deleteDirectory(baseDir);
    }
    
    private DavResource getDavResource(String logicalPath, File file)
    {
        return new ArchivaDavResource(logicalPath, file.getAbsolutePath(), mimeTypes, session, resourceLocator, null);
    }
    
    public void testIsLockable()
    {
        assertTrue(resource.isLockable(Type.WRITE, Scope.EXCLUSIVE));
        assertFalse(resource.isLockable(Type.WRITE, Scope.SHARED));
    }
    
    public void testLock()
        throws Exception
    {
        assertEquals(0, resource.getLocks().length);
       
        LockInfo info = new LockInfo(Scope.EXCLUSIVE, Type.WRITE, "/", 0, false);
        lockManager.createLock(info, resource);
        
        assertEquals(1, resource.getLocks().length);
    }
    
    public void testLockIfResourceUnlockable()
        throws Exception
    {
        assertEquals(0, resource.getLocks().length);
       
        LockInfo info = new LockInfo(Scope.SHARED, Type.WRITE, "/", 0, false);
        try
        {
            lockManager.createLock(info, resource);
            fail("Did not throw dav exception");
        }
        catch (Exception e)
        {
            //Simple lock manager will die
        }
        assertEquals(0, resource.getLocks().length); 
    }
    
    public void testGetLock()
        throws Exception
    {
        LockInfo info = new LockInfo(Scope.EXCLUSIVE, Type.WRITE, "/", 0, false);
        lockManager.createLock(info, resource);
        
        assertEquals(1, resource.getLocks().length);
        
        //Lock should exist
        assertNotNull(resource.getLock(Type.WRITE, Scope.EXCLUSIVE));
        
        //Lock should not exist
        assertNull(resource.getLock(Type.WRITE, Scope.SHARED));
    }
    
    
    public void testRefreshLockThrowsExceptionIfNoLockIsPresent()
        throws Exception
    {
        LockInfo info = new LockInfo(Scope.EXCLUSIVE, Type.WRITE, "/", 0, false);
        
        assertEquals(0, resource.getLocks().length);       
        
        try
        {
            lockManager.refreshLock(info, "notoken", resource);
            fail("Did not throw dav exception");
        }
        catch (DavException e)
        {
            assertEquals(DavServletResponse.SC_PRECONDITION_FAILED, e.getErrorCode());
        }
        
        assertEquals(0, resource.getLocks().length);
    }
    
    public void testRefreshLock()
        throws Exception
    {
        LockInfo info = new LockInfo(Scope.EXCLUSIVE, Type.WRITE, "/", 0, false);
        
        assertEquals(0, resource.getLocks().length);
        
        lockManager.createLock(info, resource);
        
        assertEquals(1, resource.getLocks().length);
        
        ActiveLock lock = resource.getLocks()[0];

        lockManager.refreshLock(info, lock.getToken(), resource);
        
        assertEquals(1, resource.getLocks().length);
    }
    
    public void testUnlock()
        throws Exception
    {
        LockInfo info = new LockInfo(Scope.EXCLUSIVE, Type.WRITE, "/", 0, false);
        
        assertEquals(0, resource.getLocks().length);
        
        lockManager.createLock(info, resource);
        
        assertEquals(1, resource.getLocks().length);
        
        ActiveLock lock = resource.getLocks()[0];

        lockManager.releaseLock(lock.getToken(), resource);
        
        assertEquals(0, resource.getLocks().length);
    }    
    
    public void testUnlockThrowsDavExceptionIfNotLocked()
        throws Exception
    {
        LockInfo info = new LockInfo(Scope.EXCLUSIVE, Type.WRITE, "/", 0, false);
        
        assertEquals(0, resource.getLocks().length);
        
        lockManager.createLock(info, resource);
        
        assertEquals(1, resource.getLocks().length);

        try
        {
            lockManager.releaseLock("BLAH", resource);
            fail("Did not throw DavException");
        }
        catch (DavException e)
        {
            assertEquals(DavServletResponse.SC_LOCKED, e.getErrorCode());
        }
        
        assertEquals(1, resource.getLocks().length);      
    }
    
    public void testUnlockThrowsDavExceptionIfResourceNotLocked()
        throws Exception
    {        
        assertEquals(0, resource.getLocks().length);

        try
        {
            lockManager.releaseLock("BLAH", resource);
            fail("Did not throw DavException");
        }
        catch (DavException e)
        {
            assertEquals(DavServletResponse.SC_PRECONDITION_FAILED, e.getErrorCode());
        }
        
        assertEquals(0, resource.getLocks().length);      
    }
}

@@ -1941,22 +1941,16 @@
 private 
-final 
 File myR
@@ -1960,38 +1960,8 @@
 urce
- = new File(baseDir, REPOPATH)
 ;%0A  
@@ -2316,20 +2316,23 @@
 seDir = 
-new 
+getTest
 File(%22ta
@@ -2377,24 +2377,82 @@
 r.mkdirs();%0A
+        myResource = new File(baseDir, %22myresource.jar%22);%0A
         myRe

stop file being created in / - tests still fail though