package org.greenstone.gatherer.remote;

import java.io.*;
import java.util.zip.*;


/**
 */
public class ZipCollectionArchives
{
    static public void main(String[] args)
    {
	if (args.length != 3) {
	    System.err.println("Usage: ZipCollectionArchives <zip-file> <collect-directory-path> <collection-name>");
	    return;
	}

	String zip_file_path = args[0];
	String collect_directory_path = args[1];
	String collection_name = args[2];

	if (!collect_directory_path.endsWith(File.separator)) {
	    collect_directory_path += File.separator;
	}

 	try {
	    ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip_file_path));

	    // Add archives directory, with doc.xml files only
	    String archives_relative_path = collection_name + File.separator + "archives";
	    ZipTools.ZipFilter collection_archives_zip_filter = new CollectionArchivesZipFilter();
	    ZipTools.addFileToZip(zos, collect_directory_path, archives_relative_path, collection_archives_zip_filter);

	    zos.close();
	}
	catch (Exception exception) {
	    exception.printStackTrace();
	}
    }


    static public class CollectionArchivesZipFilter
	extends ZipTools.NullZipFilter
    {
	private byte[] bytes_remaining = new byte[0];
	private int section_depth = 0;
	private boolean in_section_content = false;


	public boolean shouldIncludeFile(String relative_file_path)
	{
	    // Only doc.xml files are strictly required, but we include archives.inf as well to prevent
	    //   errors when zipping up the archives of a collection where no files were imported
	    //   (in this case the zip file would contain nothing at all)
	    return (relative_file_path.equals("archives.inf") || relative_file_path.endsWith(File.separator + "archives.inf") || relative_file_path.equals("doc.xml") || relative_file_path.endsWith(File.separator + "doc.xml"));
	}


	public boolean shouldIncludeFileContent(String relative_file_path)
	{
	    // Only content for doc.xml files is included
	    return (relative_file_path.equals("doc.xml") || relative_file_path.endsWith(File.separator + "doc.xml"));
	}


	public void filterFileContent(String relative_file_path, BufferedInputStream bis, ZipOutputStream zos)
	{
	    // Reset the status in case there were errors in previous doc.xml files
	    section_depth = 0;
	    in_section_content = false;

	    // Filter out the <Content>...</Content> of the doc.xml files
	    try {
		BufferedReader reader = new BufferedReader(new InputStreamReader(bis, "UTF-8"));
		String line = null;
		while ((line = reader.readLine()) != null) {
		    // If this line isn't filtered, write it out to zos
		    if (!filterFileLine(line)) {
			line += "\n";
			byte[] bytes = line.getBytes("UTF-8");
			zos.write(bytes, 0, bytes.length);
		    }
		}
	    }
	    catch (Exception exception) {
		exception.printStackTrace();
	    }
	}


	private boolean filterFileLine(String line)
	{
	    boolean filter_line = false;

	    if (line.indexOf("<Section>") != -1) {
		section_depth++;
	    }
	    if (line.indexOf("<Content>") != -1) {
		in_section_content = true;
	    }

	    // If we're in a subsection or in a content element, filter this line
	    if (section_depth > 1 || in_section_content) {
		filter_line = true;
	    }

	    if (line.indexOf("</Content>") != -1) {
		in_section_content = false;
	    }
	    if (line.indexOf("</Section>") != -1) {
		section_depth--;
	    }

	    return filter_line;
	}
    }
}
