package org.greenstone.gatherer.remote;

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


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

	String zip_file_path = args[0];
	String collect_directory_path = args[1];
	String user_name = args[2];
	String user_groups = args[3];

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

 	try {
	    ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip_file_path));
	    ZipTools.ZipFilter collection_etc_zip_filter = new CollectionEtcZipFilter();
	    ZipTools.ZipFilter collection_metadata_zip_filter = new CollectionMetadataZipFilter();

	    addUserAccessibleCollections(collect_directory_path, "", collect_directory, zos, 
					 collection_etc_zip_filter, collection_metadata_zip_filter,
					 user_name, user_groups);

	    

	    zos.putNextEntry(new ZipEntry(".gli"));
	    zos.close();
	}
	catch (Exception exception) {
	    exception.printStackTrace();
	}
    }

    static private void addUserAccessibleCollections(String toplevel_path,        // remains unchanged
						     String relative_path,        // grows with each level of recursion
						     File collect_directory,      // current collection (group) directory being considered
						     ZipOutputStream zos, 
						     ZipTools.ZipFilter collection_etc_zip_filter,
						     ZipTools.ZipFilter collection_metadata_zip_filter,
						     String user_name,
						     String user_groups) 
    {
	
	if(!relative_path.equals("")) {
	    relative_path += File.separator;
	}
	
	// Add the etc and metadata directories from each of the collections the user has access to
	File[] collection_directories = collect_directory.listFiles();
	for (int i = 0; i < collection_directories.length; i++) {
	    if (collection_directories[i].isDirectory()) {
		String collection_name = collection_directories[i].getName();
		if (checkAccess(collection_name, user_name, user_groups)) {
		    
		    String etc_relative_path = relative_path + collection_directories[i].getName() + File.separator + "etc";
		    ZipTools.addFileToZip(zos, toplevel_path, etc_relative_path, collection_etc_zip_filter);
		    
		    // The "metadata" directory may not exist (non-GLI collections)
		    String metadata_relative_path = relative_path + collection_directories[i].getName() + File.separator + "metadata";
		    File metadata_directory = new File(toplevel_path + File.separator + metadata_relative_path);
		    if (metadata_directory.exists()) {
			ZipTools.addFileToZip(zos, toplevel_path, metadata_relative_path, collection_metadata_zip_filter);
		    } 
		    else { // if a collection contains no metadata directory, then check if it is a collectgroup
			
			// read from collection config file in etc folder
			File config_file = new File(collection_directories[i], "etc"+File.separator+"collect.cfg");
			if(config_file.exists()) {
			    try {
				BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(config_file)));
				String line = null;
				while((line = reader.readLine()) != null) { // read lines and look for: collectgroup true
				    line = line.trim(); // need to ignore surrounding whitespace
				    if(line.startsWith("collectgroup") && line.endsWith("true")) {
					// if collectgroup, then recurse on current folder
					addUserAccessibleCollections(toplevel_path, relative_path+collection_directories[i].getName(), collection_directories[i],
								     zos, collection_etc_zip_filter, collection_metadata_zip_filter,
								     user_name, user_groups);
				    }
				}
				
				reader.close();
			    } catch(Exception e) {
				System.err.println("Exception reading from file " + config_file + ": " + e);
				e.printStackTrace();
			    }
			}			    
		    }
		}
	    }
	}
    }


    static private boolean checkAccess(String collection_name, String user_name, String user_groups)
    {
	String[] user_groups_array = user_groups.split(",");
	for (int i = 0; i < user_groups_array.length; i++) {
          if (user_groups_array[i].equals("administrator") || user_groups_array[i].equals("all-collections-editor")) {
		return true;
	    }
            if (user_groups_array[i].equals("shared-collections-editor") && !collection_name.contains("@")) {
              return true;
            }
	    if (user_groups_array[i].equals("personal-collections-editor") && collection_name.startsWith(user_name + "@")) {
		return true;
	    }
	    if (user_groups_array[i].equals(collection_name + "-collection-editor")) {
		return true;
	    }
	}

	return false;
    }


    static private class CollectionEtcZipFilter
	extends ZipTools.NullZipFilter
    {
	public boolean shouldIncludeFile(String relative_file_path)
	{
	    // Only collect.cfg files are included
	    if (relative_file_path.endsWith("collect.cfg")){
		return (relative_file_path.equals("collect.cfg") || relative_file_path.endsWith(File.separator + "collect.cfg"));
	    }

	    // Only collectConfig.xml files are included
	    if (relative_file_path.endsWith("collectionConfig.xml")){
		return (relative_file_path.equals("collectionConfig.xml") || relative_file_path.endsWith(File.separator + "collectionConfig.xml"));
	    }
	    return false;
	}
    }


    static private class CollectionMetadataZipFilter
	extends ZipTools.NullZipFilter
    {
	public boolean shouldIncludeFileContent(String relative_file_path)
	{
	    // We don't include content for any of the metadata set files
	    return false;
	}
    }
}
