/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation.  All rights 
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer. 
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution,
*    if any, must include the following acknowledgment:  
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowledgment may appear in the software itself,
*    if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must 
*    not be used to endorse or promote products derived from this
*    software without prior written permission. For written 
*    permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache 
*    XMLBeans", nor may "Apache" appear in their name, without prior 
*    written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems 
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/

package org.apache.xmlbeans.impl.tool;

import org.apache.xmlbeans.impl.common.IOUtil;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.FileFilter;
import java.io.OutputStream;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.HashSet;
import java.util.Set;

public class SchemaResourceManager extends BaseSchemaResourceManager
{
    public static void main(String[] args) throws IOException
    {
        if (args.length == 0)
        {
            System.out.println("Maintains \"xsdownload.xml\", an index of locally downloaded .xsd files");
            System.out.println("usage: sdownload [-dir directory] [-refresh] [-recurse] [-sync] [url/file...]");
            System.out.println("");
            System.out.println("URLs that are specified are downloaded if they aren't already cached.");
            System.out.println("In addition:");
            System.out.println("  -dir specifies the directory for the xsdownload.xml file (default .).");
            System.out.println("  -sync synchronizes the index to any local .xsd files in the tree.");
            System.out.println("  -recurse recursively downloads imported and included .xsd files.");
            System.out.println("  -refresh redownloads all indexed .xsd files.");
            System.out.println("If no files or URLs are specified, all indexed files are relevant.");
            System.exit(0);
            return;
        }

        Set opts = new HashSet();
        opts.add("dir");
        CommandLine cl = new CommandLine(args, opts);
        if (cl.getOpt("license") != null)
        {
            CommandLine.printLicense();
            System.exit(0);
            return;
        }
        
        args = cl.args();

        boolean sync = (cl.getOpt("sync") != null);
        boolean refresh = (cl.getOpt("refresh") != null);
        boolean imports = (cl.getOpt("recurse") != null);
        String dir = cl.getOpt("dir");
        if (dir == null)
            dir = ".";
        File directory = new File(dir);

        SchemaResourceManager mgr;
        try
        {
            mgr = new SchemaResourceManager(directory);
        }
        catch (IllegalStateException e)
        {
            if (e.getMessage() != null)
                System.out.println(e.getMessage());
            else
                e.printStackTrace();
            System.exit(1);
            return;
        }

        List uriList = new ArrayList();
        List fileList = new ArrayList();
        for (int i = 0; i < args.length; i++)
        {
            if (looksLikeURL(args[i]))
            {
                uriList.add(args[i]);
            }
            else
            {
                fileList.add(new File(directory, args[i]));
            }
        }

        // deal with files that are not in the proper directory
        for (Iterator i = fileList.iterator(); i.hasNext(); )
        {
            File file = (File)i.next();
            if (!isInDirectory(file, directory))
            {
                System.err.println("File not within directory: " + file);
                i.remove();
            }
        }

        // deal with directories
        fileList = collectXSDFiles((File[])fileList.toArray(new File[0]));

        String[] uris = (String[])uriList.toArray(new String[0]);
        File[] files = (File[])fileList.toArray(new File[0]);
        String[] filenames = relativeFilenames(files, directory);

        if (uris.length + filenames.length > 0)
        {
            mgr.process(uris, filenames, sync, refresh, imports);
        }
        else
        {
            mgr.processAll(sync, refresh, imports);
        }

        mgr.writeCache();
        System.exit(0);
    }

    private static boolean looksLikeURL(String str)
    {
        return str.startsWith("http:") || str.startsWith("https:") || str.startsWith("ftp:") || str.startsWith("file:");
    }

    private static String relativeFilename(File file, File directory)
    {
        if (file == null || file.equals(directory))
            return ".";
        return relativeFilename(file.getParentFile(), directory) + "/" + file.getName();
    }

    private static String[] relativeFilenames(File[] files, File directory)
    {
        String[] result = new String[files.length];
        for (int i = 0; i < files.length; i++)
        {
            result[i] = relativeFilename(files[i], directory);
        }
        return result;
    }

    private static boolean isInDirectory(File file, File dir)
    {
        if (file == null)
            return false;
        if (file.equals(dir))
            return true;
        return isInDirectory(file.getParentFile(), dir);
    }





    public SchemaResourceManager(File directory)
    {
        _directory = directory;
        init();
    }

    private File _directory;


    // SOME METHODS TO OVERRIDE ============================

    /**
     * Sends messages to System.out.
     */
    protected void warning(String msg)
    {
        System.out.println(msg);
    }

    /**
     * Returns true if the given filename exists.  The filenames
     * are of the form "/foo/bar/zee.xsd" and should be construed
     * as rooted at the root of the project.
     */
    protected boolean fileExists(String filename)
    {
        return (new File(_directory, filename)).exists();
    }

    /**
     * Gets the data in the given filename as an InputStream.
     */
    protected InputStream inputStreamForFile(String filename) throws IOException
    {
        return new FileInputStream(new File(_directory, filename));
    }

    /**
     * Writes an entire file in one step.  An InputStream is passed and
     * copied to the file.
     */
    protected void writeInputStreamToFile(InputStream input, String filename) throws IOException
    {
        File targetFile = new File(_directory, filename);

        File parent = targetFile.getParentFile();
        if (!parent.exists())
            parent.mkdirs();
        OutputStream output = new FileOutputStream(targetFile);
        IOUtil.copyCompletely(input, output);
    }

    /**
     * Deletes a file.  Sometimes immediately after writing a new file
     * we notice that it's exactly the same as an existing file and
     * we delete it. We never delete a file that was given to us
     * by the user.
     */
    protected void deleteFile(String filename)
    {
        new File(_directory, filename).delete();
    }

    /**
     * Returns a list of all the XSD filesnames in the project.
     */
    protected String[] getAllXSDFilenames()
    {
        File[] allFiles = (File[])collectXSDFiles(new File[] { _directory }).toArray(new File[0]);
        return relativeFilenames(allFiles, _directory);
    }

    /**
     * Simple recursive file filter to do the above.
     */
    private static List collectXSDFiles(File[] dirs)
    {
        List files = new ArrayList();
        for (int i = 0; i < dirs.length; i++)
        {
            File f = dirs[i];
            if (!f.isDirectory())
            {
                files.add(f);
            }
            else
            {
                files.addAll(collectXSDFiles(
                    f.listFiles(new FileFilter()
                    {
                        public boolean accept(File file)
                            { return file.isDirectory() ||
                              file.isFile() &&
                              file.getName().endsWith(".xsd"); }
                    }
                )));
            }
        }
        return files;
    }

}
