//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.util.resource;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.InvalidPathException;
import java.nio.file.StandardOpenOption;
import java.security.Permission;

import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;


/* ------------------------------------------------------------ */
/** File Resource.
 *
 * Handle resources of implied or explicit file type.
 * This class can check for aliasing in the filesystem (eg case
 * insensitivity).  By default this is turned on, or it can be controlled 
 * by calling the static method @see FileResource#setCheckAliases(boolean)
 *
 * @deprecated Use {@link PathResource}
 */
@Deprecated
public class FileResource extends Resource
{
    private static final Logger LOG = Log.getLogger(FileResource.class);

    /* ------------------------------------------------------------ */
    private final File _file;
    private final URI _uri;
    private final URI _alias;
    
    /* -------------------------------------------------------- */
    public FileResource(URL url)
            throws IOException, URISyntaxException
    {
        File file;
        try
        {
            // Try standard API to convert URL to file.
            file =new File(url.toURI());
            assertValidPath(file.toString());
        }
        catch (URISyntaxException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            if (!url.toString().startsWith("file:"))
                throw new IllegalArgumentException("!file:");
            
            LOG.ignore(e);
            try
            {
                // Assume that File.toURL produced unencoded chars. So try encoding them.
                String file_url="file:"+URIUtil.encodePath(url.toString().substring(5));
                URI uri = new URI(file_url);
                if (uri.getAuthority()==null)
                    file = new File(uri);
                else
                    file = new File("//"+uri.getAuthority()+URIUtil.decodePath(url.getFile()));
            }
            catch (Exception e2)
            {
                LOG.ignore(e2);
                // Still can't get the file.  Doh! try good old hack!
                URLConnection connection=url.openConnection();
                Permission perm = connection.getPermission();
                file = new File(perm==null?url.getFile():perm.getName());
            }
        }
        
        _file=file;
        _uri=normalizeURI(_file,url.toURI());
        _alias=checkFileAlias(_uri,_file);
    }

    /* -------------------------------------------------------- */
    public FileResource(URI uri)
    {
        File file=new File(uri);
        _file=file;
        try
        {
            URI file_uri = _file.toURI();
            _uri = normalizeURI(_file, uri);
            assertValidPath(file.toString());

            // Is it a URI alias?
            if (!URIUtil.equalsIgnoreEncodings(_uri.toASCIIString(), file_uri.toString()))
                _alias = _file.toURI();
            else
                _alias = checkFileAlias(_uri, _file);
        }
        catch (URISyntaxException e)
        {
            throw new InvalidPathException(_file.toString(), e.getMessage())
            {
                {
                    initCause(e);
                }
            };
        }
    }

    /* -------------------------------------------------------- */
    public FileResource(File file)
    {
        assertValidPath(file.toString());
        _file=file;
        try
        {
            _uri = normalizeURI(_file, _file.toURI());
        }
        catch (URISyntaxException e)
        {
            throw new InvalidPathException(_file.toString(), e.getMessage())
            {
                {
                    initCause(e);
                }
            };
        }
        _alias=checkFileAlias(_uri,_file);
    }

    /* -------------------------------------------------------- */
    public FileResource(File base, String childPath)
    {
        String encoded = URIUtil.encodePath(childPath);

        _file = new File(base, childPath);

        // The encoded path should be a suffix of the resource (give or take a directory / )
        URI uri;
        try
        {
            if (base.isDirectory())
            {
                // treat all paths being added as relative
                uri=new URI(URIUtil.addEncodedPaths(base.toURI().toASCIIString(),encoded));
            }
            else
            {
                uri=new URI(base.toURI().toASCIIString()+encoded);
            }
        }
        catch (final URISyntaxException e)
        {
            throw new InvalidPathException(base.toString() + childPath, e.getMessage())
            {
                {
                    initCause(e);
                }
            };
        }

        _uri=uri;
        _alias=checkFileAlias(_uri,_file);
    }

    /* -------------------------------------------------------- */
    private static URI normalizeURI(File file, URI uri) throws URISyntaxException {
        String u =uri.toASCIIString();
        if (file.isDirectory())
        {
            if(!u.endsWith("/"))
                u+="/";
        }
        else if (file.exists() && u.endsWith("/"))
            u=u.substring(0,u.length()-1);
        return new URI(u);
    }

    /* -------------------------------------------------------- */
    private static URI checkFileAlias(final URI uri, final File file)
    {
        try
        {
            if (!URIUtil.equalsIgnoreEncodings(uri,file.toURI()))
            {
                // Return alias pointing to Java File normalized URI
                return new File(uri).getAbsoluteFile().toURI();
            }

            String abs=file.getAbsolutePath();
            String can=file.getCanonicalPath();

            if (!abs.equals(can))
            {
                if (LOG.isDebugEnabled())
                    LOG.debug("ALIAS abs={} can={}",abs,can);

                URI alias=new File(can).toURI();
                // Have to encode the path as File.toURI does not!
                return new URI("file://"+URIUtil.encodePath(alias.getPath()));
            }
        }
        catch(Exception e)
        {
            LOG.warn("bad alias for {}: {}",file,e.toString());
            LOG.debug(e);
            try
            {
                return new URI("http://eclipse.org/bad/canonical/alias");
            }
            catch(Exception e2)
            {
                LOG.ignore(e2);
                throw new RuntimeException(e);
            }
        }

        return null;
    }
    
    /* -------------------------------------------------------- */
    @Override
    public Resource addPath(String path)
            throws IOException, MalformedURLException
    {
        assertValidPath(path);
        path = org.eclipse.jetty.util.URIUtil.canonicalPath(path);

        if (path==null)
            throw new MalformedURLException();
        
        if ("/".equals(path))
            return this;

        return new FileResource(_file, path);
    }

    private void assertValidPath(String path)
    {
        int idx = StringUtil.indexOfControlChars(path);
        if (idx >= 0)
        {
            throw new InvalidPathException(path, "Invalid Character at index " + idx);
        }
    }

    /* ------------------------------------------------------------ */
    @Override
    public URI getAlias()
    {
        return _alias;
    }
    
    /* -------------------------------------------------------- */
    /**
     * Returns true if the resource exists.
     */
    @Override
    public boolean exists()
    {
        return _file.exists();
    }
        
    /* -------------------------------------------------------- */
    /**
     * Returns the last modified time
     */
    @Override
    public long lastModified()
    {
        return _file.lastModified();
    }

    /* -------------------------------------------------------- */
    /**
     * Returns true if the resource is a container/directory.
     */
    @Override
    public boolean isDirectory()
    {
        return _file.exists() && _file.isDirectory() || _uri.toASCIIString().endsWith("/");
    }

    /* --------------------------------------------------------- */
    /**
     * Return the length of the resource
     */
    @Override
    public long length()
    {
        return _file.length();
    }
        

    /* --------------------------------------------------------- */
    /**
     * Returns the name of the resource
     */
    @Override
    public String getName()
    {
        return _file.getAbsolutePath();
    }
        
    /* ------------------------------------------------------------ */
    /**
     * Returns an File representing the given resource or NULL if this
     * is not possible.
     */
    @Override
    public File getFile()
    {
        return _file;
    }
        
    /* --------------------------------------------------------- */
    /**
     * Returns an input stream to the resource
     */
    @Override
    public InputStream getInputStream() throws IOException
    {
        return new FileInputStream(_file);
    }

    /* ------------------------------------------------------------ */
    @Override
    public ReadableByteChannel getReadableByteChannel() throws IOException
    {
        return FileChannel.open(_file.toPath(),StandardOpenOption.READ);
    }
        
    /* --------------------------------------------------------- */
    /**
     * Deletes the given resource
     */
    @Override
    public boolean delete()
            throws SecurityException
    {
        return _file.delete();
    }

    /* --------------------------------------------------------- */
    /**
     * Rename the given resource
     */
    @Override
    public boolean renameTo( Resource dest)
            throws SecurityException
    {
        if( dest instanceof FileResource)
            return _file.renameTo( ((FileResource)dest)._file);
        else
            return false;
    }

    /* --------------------------------------------------------- */
    /**
     * Returns a list of resources contained in the given resource
     */
    @Override
    public String[] list()
    {
        String[] list =_file.list();
        if (list==null)
            return null;
        for (int i=list.length;i-->0;)
        {
            if (new File(_file,list[i]).isDirectory() &&
                    !list[i].endsWith("/"))
                list[i]+="/";
        }
        return list;
    }
    
    /* ------------------------------------------------------------ */
    /**
     * @param o the object to compare against this instance
     * @return <code>true</code> of the object <code>o</code> is a {@link FileResource} pointing to the same file as this resource. 
     */
    @Override
    public boolean equals( Object o)
    {
        if (this == o)
            return true;

        if (null == o || ! (o instanceof FileResource))
            return false;

        FileResource f=(FileResource)o;
        return f._file == _file || (null != _file && _file.equals(f._file));
    }

    /* ------------------------------------------------------------ */
    /**
     * @return the hashcode.
     */
    @Override
    public int hashCode()
    {
        return null == _file ? super.hashCode() : _file.hashCode();
    }
    
    /* ------------------------------------------------------------ */
    @Override
    public void copyTo(File destination)
            throws IOException
    {
        if (isDirectory())
        {
            IO.copyDir(getFile(),destination);
        }
        else
        {
            if (destination.exists())
                throw new IllegalArgumentException(destination+" exists");
            IO.copy(getFile(),destination);
        }
    }

    @Override
    public boolean isContainedIn(Resource r) throws MalformedURLException
    {
        return false;
    }

    @Override
    public void close()
    {
    }

    @Override
    public URL getURL()
    {
        try
        {
            return _uri.toURL();
        }
        catch (MalformedURLException e)
        {
            throw new IllegalStateException(e);
        }
    }
    
    @Override
    public URI getURI()
    {
        return _uri;
    }

    @Override
    public String toString()
    {
        return _uri.toString();
    }
}