package org.exist.backup;

import java.io.IOException;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.Properties;
import java.util.Date;

import org.exist.util.EXistInputSource;
import org.exist.util.ZipEntryInputSource;
import org.exist.xquery.value.DateTimeValue;
import org.exist.xquery.XPathException;

public class ZipArchiveBackupDescriptor extends AbstractBackupDescriptor
{
	protected ZipFile archive;
	protected ZipEntry descriptor;
	protected String base;

	public ZipArchiveBackupDescriptor(File fileArchive)
		throws ZipException,IOException,FileNotFoundException
	{
		archive=new ZipFile(fileArchive);
		base="db/";
		descriptor=archive.getEntry(base+BackupDescriptor.COLLECTION_DESCRIPTOR);
		if(descriptor==null || descriptor.isDirectory()) {
			throw new FileNotFoundException("Archive "+fileArchive.getAbsolutePath()+" is not a valid eXist backup archive");
		}
	}
	
	private ZipArchiveBackupDescriptor(ZipFile archive,String base)
		throws FileNotFoundException
	{
		this.archive=archive;
		this.base=base;
		descriptor=archive.getEntry(base+BackupDescriptor.COLLECTION_DESCRIPTOR);
		if(descriptor==null || descriptor.isDirectory()) {
			throw new FileNotFoundException(archive.getName()+" is a bit corrupted ("+base+" descriptor not found): not a valid eXist backup archive");
		}
	}
	
	public BackupDescriptor getChildBackupDescriptor(String describedItem) {
		BackupDescriptor bd=null;
		try {
			bd=new ZipArchiveBackupDescriptor(archive,base+describedItem+"/");
		} catch(FileNotFoundException fnfe) {
			// DoNothing(R)
		}
		
		return bd;
	}

    public BackupDescriptor getBackupDescriptor(String describedItem) {
        if (describedItem.length() > 0 && describedItem.charAt(0) == '/')
            describedItem = describedItem.substring(1);
        if (!describedItem.endsWith("/"))
            describedItem = describedItem + '/';
        BackupDescriptor bd = null;
        try {
            bd = new ZipArchiveBackupDescriptor(archive, describedItem);
        } catch (FileNotFoundException e) {
            // DoNothing(R)
        }
        return bd;
    }

    public EXistInputSource getInputSource() {
		return new ZipEntryInputSource(archive,descriptor);
	}

	public EXistInputSource getInputSource(String describedItem) {
		ZipEntry ze = archive.getEntry(base+describedItem);
		EXistInputSource retval=null;
		if(ze!=null && !ze.isDirectory()) {
			retval=new ZipEntryInputSource(archive,ze);
		}
		
		return retval;
	}

	public String getSymbolicPath() {
		return archive.getName()+"#"+descriptor.getName();
	}
	
	public String getSymbolicPath(String describedItem,boolean isChildDescriptor) {
		String retval=archive.getName()+"#"+base+describedItem;
		if(isChildDescriptor)
			retval+="/"+BackupDescriptor.COLLECTION_DESCRIPTOR;
		return retval;
	}

    public Properties getProperties() throws IOException {
        Properties properties = null;
        ZipEntry ze = archive.getEntry(BACKUP_PROPERTIES);
        if (ze != null) {
            properties = new Properties();
            properties.load(archive.getInputStream(ze));
        }
        return properties;
    }

    public File getParentDir() {
        return new File(archive.getName()).getParentFile();
    }


    public String getName() {
        return new File(archive.getName()).getName();
    }
}

@@ -199,24 +199,54 @@
 ip.ZipFile;%0A
+import java.util.Enumeration;%0A
 import java.
@@ -262,16 +262,16 @@
 erties;%0A
-
 import j
@@ -763,16 +763,42 @@
 chive);%0A
+%09%09%0A%09%09//is it full backup?%0A
 %09%09base=%22
@@ -871,32 +871,32 @@
 ON_DESCRIPTOR);%0A
-
 %09%09if(descriptor=
@@ -924,32 +924,703 @@
 sDirectory()) %7B%0A
+%09%09%09%0A%09%09%09base = null;%0A%09%09%09//looking for highest collection%0A%09%09%09//TODO: better to put some information on top? %0A%09%09%09ZipEntry item = null;%0A%09%09%09Enumeration zipEnum = archive.entries();%0A%09%09%09while(zipEnum.hasMoreElements()) %7B%0A%09%09%09%09item = (ZipEntry) zipEnum.nextElement();%0A%0A%09%09%09%09if (!item.isDirectory()) %7B%0A%09%09%09%09%09if (item.getName().endsWith(BackupDescriptor.COLLECTION_DESCRIPTOR)) %7B%0A%09%09%09%09%09%09if (base == null %7C%7C base.length() %3E item.getName().length()) %7B%0A%09%09%09%09%09%09%09descriptor = item;%0A%09%09%09%09%09%09%09base = item.getName();%0A%09%09%09%09%09%09%7D%0A%09%09%09%09%09%7D%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%09%0A%09%09%09if (base != null)%0A%09%09%09%09base = base.substring(0, base.length() - BackupDescriptor.COLLECTION_DESCRIPTOR.length());%0A%09%09%7D%0A%0A%09%09if (descriptor == null) %7B%0A
 %09%09%09throw new Fil

unable to restore subcollection from 1.4 backup