/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/testsuite/junit/store/org/apache/slide/store/tamino/tools/repairer/RepairTest.java,v 1.1 2004/03/25 16:18:15 juergen Exp $
 * $Revision: 1.1 $
 * $Date: 2004/03/25 16:18:15 $
 *
 * ====================================================================
 *
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * Licensed 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.
 */

package org.apache.slide.store.tamino.tools.repairer;

import junit.framework.TestCase;
import junit.textui.TestRunner;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionNumber;
import org.apache.slide.store.tamino.Configuration;
import org.apache.slide.store.tamino.jdomobjects.XDescriptors;
import org.apache.slide.store.tamino.jdomobjects.XDescriptorsUtil;
import org.apache.slide.store.tamino.tools.repairer.ContentCheck;
import org.apache.slide.store.tamino.tools.repairer.DocumentEnabler;
import org.apache.slide.store.tamino.tools.repairer.NamespaceConsistencyCheck;
import org.apache.slide.store.tamino.tools.repairer.UniqueContentIdCheck;
import org.apache.slide.store.tamino.tools.repairer.UniqueDescriptorsIdCheck;
import org.apache.slide.util.Misc;

public class RepairTest extends TestCase {
    private RepairHelper impl;
    
    public RepairTest (String name) {
        super (name);
    }
    
    /**
     ** Start precisely this test suite with the commandline interface.
     **
     ** @pre   true
     ** @post  true
     **
     ** @param args   commandline options (none are evaluated)
     **/
    public static void main( String[] args ) {
        TestRunner.run( new RepairTest("testUniqueDescriptorsIdCheck") );
        //TestRunner.run( RepairTest.class );
    }
    
    /**
     ** Construct your fixtures for the test cases in CaseTemplate.
     **
     ** @pre   true
     ** @post  true
     **/
    protected void setUp() throws Exception {
        super.setUp();
        
        impl = new RepairHelper(Configuration.get().namespace);
        impl.wipeDatabase();
    }
    
    /**
     * this test try to repair missing directory entries metadata.
     **/
    public void testInvalidDescriptor() throws Exception {
        String uuri = impl.doCreate("/test/test2.xml");
        XDescriptors d = impl.taminoClient.getDescriptorsAccessor().readOneRwDescriptorsByUuri(uuri);
        d.setReadOnly(false);
        d.removeObjectNode();
        impl.taminoClient.getDescriptorsAccessor().update(d);
        impl.taminoClient.commit();
        impl.testRepairer(Misc.lst(ContentCheck.RemoveDescriptor.class),
                          Misc.lst(ContentCheck.RemoveDescriptor.class, NamespaceConsistencyCheck.RemoveReference.class),
                          // TODO: patch itself has to Create metadata -- wait for collection enabler
                          Misc.lst(DocumentEnabler.class)
                         );
    }
    
    /**
     * this test try to repair the metadata in case of a non-existing document.
     **/
    public void testnonExistingDocument() throws Exception {
        impl.doCreate("/test/meta/test2.xml");
        impl.taminoClient.deleteContent("/*");
        impl.testRepairer(Misc.lst(ContentCheck.RemoveDescriptor.class),
                          Misc.lst(ContentCheck.RemoveDescriptor.class, NamespaceConsistencyCheck.RemoveReference.class));
    }
    
    /**
     * this test try to find out not unique uri's in metadata.
     **/
    public void testUniqueContentIdCheck() throws Exception {
        String origUuri;
        String cloneUuri;
        XDescriptors orig;
        XDescriptors clone;
        
        origUuri = impl.doCreate("/test/another/one/test1.xml");
        cloneUuri = impl.doCreate("/test/another/two/test1.xml");  // files have to be the same, otherwise the contentlength gets wrong as well
        orig = impl.taminoClient.getDescriptorsAccessor().readOneRwDescriptorsByUuri(origUuri);
        clone = impl.taminoClient.getDescriptorsAccessor().readOneRwDescriptorsByUuri(cloneUuri);
        impl.taminoClient.getContentAccessor().deleteContent(XDescriptorsUtil.getContentId(clone));
        XDescriptorsUtil.setContentId(clone, XDescriptorsUtil.getContentId(orig));
        impl.taminoClient.getDescriptorsAccessor().update(clone);
        impl.taminoClient.commit();
        impl.testRepairer(Misc.lst(UniqueContentIdCheck.CopyContent.class),
                          // duplicated descriptor has been deleted - this will change if the content is copied
                          Misc.lst(UniqueContentIdCheck.CopyContent.class, NamespaceConsistencyCheck.RemoveReference.class ));
    }
    
    /**
     * this test try to find out not unique uri's in metadata.
     **/
    public void testUniqueDescriptorsIdCheck() throws Exception {
        impl.doCreate("/test/test1.xml");
        impl.doCreate("/test/test2.xml");
        impl.createDuplicateDescriptors();
        impl.testRepairer(Misc.lst(UniqueDescriptorsIdCheck.Duplicate.class),
                          Misc.lst(UniqueDescriptorsIdCheck.Duplicate.class,
                                          // only a child reference will be added - the parent
                                          // reference of the duplicated descriptor is ok
                                          NamespaceConsistencyCheck.AddReference.class));
    }
    
    public void testMissingChildRef() throws Exception {
        String uri = "/test/another/try/test2.xml";
        String childUuri = impl.doCreate(uri);
        XDescriptors child = impl.taminoClient.getDescriptorsAccessor().readOneRwDescriptorsByUuri(childUuri);
        String parentUuri = XDescriptorsUtil.getParentUuri(child);
        XDescriptors parent = impl.taminoClient.getDescriptorsAccessor().readOneRwDescriptorsByUuri(parentUuri);
        XDescriptorsUtil.removeReference(parent, childUuri, false);
        
        impl.taminoClient.getDescriptorsAccessor().update(parent);
        impl.taminoClient.commit();  // TODO: really need this?
        
        impl.testRepairer(Misc.lst(NamespaceConsistencyCheck.AddReference.class),
                          Misc.lst(NamespaceConsistencyCheck.AddReference.class));
    }
    
    public void testMissingParentRef() throws Exception {
        String uri = "/foo/test2.xml";
        String childUuri = impl.doCreate(uri);
        XDescriptors child = impl.taminoClient.getDescriptorsAccessor().readOneRwDescriptorsByUuri(childUuri);
        String parentUuri = XDescriptorsUtil.getParentUuri(child);
        XDescriptorsUtil.removeReference(child, parentUuri, true);
        impl.taminoClient.getDescriptorsAccessor().update(child);
        impl.taminoClient.commit();  // TODO: really need this?
        
        impl.testRepairer(Misc.lst(NamespaceConsistencyCheck.AddReference.class),
                          Misc.lst(NamespaceConsistencyCheck.AddReference.class));
    }
    
    public void testIncorrectContentLength() throws Exception {
        String uuri = impl.doCreate("/test/another/try/test2.xml");
        String value = "2000";
        
        XDescriptors d = impl.taminoClient.getDescriptorsAccessor().readOneRwDescriptorsByUuri(uuri);
        d.setReadOnly(false);
        NodeRevisionDescriptor revision =  d.getRevisionDescriptor(new NodeRevisionNumber(1,0));
        revision.setContentLength(value);
        d.removeRevisionDescriptor(revision);
        d.setRevisionDescriptor(revision);
        impl.taminoClient.getDescriptorsAccessor().update(d);
        impl.taminoClient.commit();
        
        impl.testRepairer(Misc.lst(ContentCheck.SetContentLength.class),
                          Misc.lst(ContentCheck.SetContentLength.class));
    }
    
    public void testGarbageFile() throws Exception {
        String childUuri = impl.doCreate("/test2.xml");
        detach(childUuri);
        impl.testRepairer(Misc.lst(NamespaceConsistencyCheck.AddReference.class, NamespaceConsistencyCheck.AddReference.class),
                          Misc.lst(NamespaceConsistencyCheck.AddReference.class, NamespaceConsistencyCheck.AddReference.class));
    }
    
    
    private void detach(String childUuri) throws Exception {
        XDescriptors child = impl.taminoClient.getDescriptorsAccessor().readOneRwDescriptorsByUuri(childUuri);
        String parentUuri = XDescriptorsUtil.getParentUuri(child);
        XDescriptors parent = impl.taminoClient.getDescriptorsAccessor().readOneRwDescriptorsByUuri(parentUuri);
        
        XDescriptorsUtil.removeReference(parent, childUuri, false);
        XDescriptorsUtil.removeReference(child, parentUuri, true);
        
        impl.taminoClient.getDescriptorsAccessor().update(parent);
        impl.taminoClient.getDescriptorsAccessor().update(child);
        impl.taminoClient.commit();  // TODO: really need this?
    }
    
    public void testGarbageTree() throws Exception {
        impl.doCreate("/foo/one/test2.xml");
        impl.doCreate("/foo/two/test2.xml");
        
        String childUuri = impl.doCreate("/foo/test2.xml");
        XDescriptors child = impl.taminoClient.getDescriptorsAccessor().readOneRwDescriptorsByUuri(childUuri);
        String parentUuri = XDescriptorsUtil.getParentUuri(child);
        detach(parentUuri);
        impl.testRepairer(Misc.lst(NamespaceConsistencyCheck.AddReference.class, NamespaceConsistencyCheck.AddReference.class),
                          // duplicated descriptor has been deleted - this will change if the content is copied
                          Misc.lst(NamespaceConsistencyCheck.AddReference.class, NamespaceConsistencyCheck.AddReference.class));
    }
}


