/*
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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.flex.utils;

import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;

import org.apache.commons.io.IOUtils;

/**
 * A collection of file related utilities.
 */
public final class FileUtils
{
    public static String canonicalPath(File file)
    {
        return canonicalFile(file).getPath();
    }

    public static File canonicalFile(File file)
    {
        try
		{
			return file.getCanonicalFile();
		}
		catch (IOException e)
		{
			return file.getAbsoluteFile();
		}
    }

    private static HashMap<String, String> filemap = null;
    private static boolean checkCase = false;

    /**
     * Canonicalize on Win32 doesn't fix the case of the file to match what is on disk.
     * Its annoying that this exists.  It will be very slow until the server stabilizes.
     * If this is called with a pattern where many files from the same directory will be
     * needed, then the cache should be changed to hold the entire directory contents
     * and check the modtime of the dir.  It didn't seem like this was worth it for now.
     * @param f A file.
     */
    public static synchronized String getTheRealPathBecauseCanonicalizeDoesNotFixCase( File f )
    {
        if (filemap == null)
        {
            filemap = new HashMap<String, String>();
            checkCase = System.getProperty("os.name").toLowerCase().startsWith("windows");
        }

        String path = FileUtils.canonicalPath( f );

        if (!checkCase || !f.exists())    // if the file doesn't exist, then we can't do anything about it.
            return path;

        // We're going to ignore the issue where someone changes the capitalization of a file on the fly.
        // If this becomes an important issue we'll have to make this cache smarter.

        if (filemap.containsKey( path ))
            return filemap.get( path );

        String file = f.getName();

        File canonfile = new File(path);

        File dir = new File(canonfile.getParent());

		// removing dir.listFiles() because it is not supproted in .NET
		String[] ss = dir.list();
        if (ss != null)
        {
            int n = ss.length;
            File[] files = new File[n];
            for (int i = 0; i < n; i++)
            {
                files[i] = new File(canonfile.getPath(), ss[i]);
            }

            for (int i = 0; i < files.length; ++i)
            {
                if (files[i].getName().equalsIgnoreCase( file ))
                {
                    filemap.put( path, files[i].getAbsolutePath() );
                    return files[i].getAbsolutePath();
                }
            }
        }
        // If we got here, it must be because we can't read the directory?
        return path;
    }

    public static URI toURI(File f) throws URISyntaxException
    {
        String s = f.getAbsolutePath();
        if (File.separatorChar != '/')
        {
            s = s.replace(File.separatorChar, '/');
        }
        if (!s.startsWith("/"))
        {
            s = "/" + s;
        }
        if (!s.endsWith("/") && f.isDirectory())
        {
            s = s + "/";
        }
        return new URI("file", s, null);
    }

	public static String addPathComponents(String p1, String p2, char sepchar)
    {
        if (p1 == null)
            p1 = "";
        if (p2 == null)
            p2 = "";

        int r1 = p1.length() - 1;

        while ((r1 >= 0) && ((p1.charAt( r1 ) == sepchar)))
            --r1;

        int r2 = 0;
        while ((r2 < p2.length()) && (p2.charAt( r2 ) == sepchar ))
            ++r2;

        String left = p1.substring( 0, r1 + 1 );
        String right = p2.substring( r2 );

        String sep = "";
        if ((left.length() > 0) && (right.length() > 0))
            sep += sepchar;

        return left + sep + right;
    }

    public static byte[] toByteArray(InputStream in)
    {
        DAByteArrayOutputStream baos = new DAByteArrayOutputStream(8192);
        byte[] buffer = new byte[8192];
        int num = 0;
        InputStream inputStream = new BufferedInputStream(in);
        try
        {
            while ((num = inputStream.read(buffer)) != -1)
            {
                baos.write(buffer, 0, num);
            }
            return baos.getDirectByteArray();
        }
        catch (IOException ex)
        {
            if (Trace.error)
                 ex.printStackTrace();
            
            // TODO Do we really want to swallow this IOException?
        }
        finally
        {
            IOUtils.closeQuietly(baos);
            
            try
            {
                if (in != null)
                    in.close();
            }
            catch (IOException ex)
            {
            }
        }

        return new byte[0];
    }

    /**
     * returns whether the file is absolute
     * if a security exception is thrown, always returns false
     */
    public static boolean isAbsolute(File f)
    {
        boolean absolute = false;
        try
        {
            absolute = f.isAbsolute();
        }
        catch (SecurityException se)
        {
            if (Trace.pathResolver)
            {
                Trace.trace(se.getMessage());
            }
        }

        return absolute;
    }
}
