/*
 * 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.commons.vfs2.provider.http;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.HeadMethod;
import org.apache.commons.httpclient.util.DateUtil;
import org.apache.commons.httpclient.util.URIUtil;
import org.apache.commons.vfs2.FileContentInfoFactory;
import org.apache.commons.vfs2.FileNotFoundException;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.FileType;
import org.apache.commons.vfs2.RandomAccessContent;
import org.apache.commons.vfs2.provider.AbstractFileName;
import org.apache.commons.vfs2.provider.AbstractFileObject;
import org.apache.commons.vfs2.provider.URLFileName;
import org.apache.commons.vfs2.util.MonitorInputStream;
import org.apache.commons.vfs2.util.RandomAccessMode;

/**
 * A file object backed by Apache Commons HttpClient.
 * <p>
 * TODO - status codes.
 *
 * @param <FS> An {@link HttpFileSystem} subclass
 */
public class HttpFileObject<FS extends HttpFileSystem> extends AbstractFileObject<FS>
{
    /**
     * An InputStream that cleans up the HTTP connection on close.
     */
    static class HttpInputStream extends MonitorInputStream
    {
        private final GetMethod method;

        public HttpInputStream(final GetMethod method)
            throws IOException
        {
            super(method.getResponseBodyAsStream());
            this.method = method;
        }

        /**
         * Called after the stream has been closed.
         */
        @Override
        protected void onClose() throws IOException
        {
            method.releaseConnection();
        }
    }
    private final String urlCharset;
    private final String userAgent;
    private final boolean followRedirect;

    private HeadMethod method;

    protected HttpFileObject(final AbstractFileName name, final FS fileSystem)
    {
        this(name, fileSystem, HttpFileSystemConfigBuilder.getInstance());
    }

    protected HttpFileObject(final AbstractFileName name, final FS fileSystem,
                             final HttpFileSystemConfigBuilder builder)
    {
        super(name, fileSystem);
        final FileSystemOptions fileSystemOptions = fileSystem.getFileSystemOptions();
        urlCharset = builder.getUrlCharset(fileSystemOptions);
        userAgent = builder.getUserAgent(fileSystemOptions);
        followRedirect = builder.getFollowRedirect(fileSystemOptions);
    }

    /**
     * Detaches this file object from its file resource.
     */
    @Override
    protected void doDetach() throws Exception
    {
        method = null;
    }

    /**
     * Returns the size of the file content (in bytes).
     */
    @Override
    protected long doGetContentSize() throws Exception
    {
        final Header header = method.getResponseHeader("content-length");
        if (header == null)
        {
            // Assume 0 content-length
            return 0;
        }
        return Long.parseLong(header.getValue());
    }

    /**
     * Creates an input stream to read the file content from.  Is only called
     * if {@link #doGetType} returns {@link FileType#FILE}.
     * <p>
     * It is guaranteed that there are no open output streams for this file
     * when this method is called.
     * <p>
     * The returned stream does not have to be buffered.
     */
    @Override
    protected InputStream doGetInputStream() throws Exception
    {
        final GetMethod getMethod = new GetMethod();
        setupMethod(getMethod);
        final int status = getAbstractFileSystem().getClient().executeMethod(getMethod);
        if (status == HttpURLConnection.HTTP_NOT_FOUND)
        {
            throw new FileNotFoundException(getName());
        }
        if (status != HttpURLConnection.HTTP_OK)
        {
            throw new FileSystemException("vfs.provider.http/get.error", getName(), Integer.valueOf(status));
        }

        return new HttpInputStream(getMethod);
    }

    /**
     * Returns the last modified time of this file.
     * <p>
     * This implementation throws an exception.
     */
    @Override
    protected long doGetLastModifiedTime() throws Exception
    {
        final Header header = method.getResponseHeader("last-modified");
        if (header == null)
        {
            throw new FileSystemException("vfs.provider.http/last-modified.error", getName());
        }
        return DateUtil.parseDate(header.getValue()).getTime();
    }

    @Override
    protected RandomAccessContent doGetRandomAccessContent(final RandomAccessMode mode) throws Exception
    {
        return new HttpRandomAccessContent(this, mode);
    }

    /**
     * Determines the type of this file.  Must not return null.  The return
     * value of this method is cached, so the implementation can be expensive.
     */
    @Override
    protected FileType doGetType() throws Exception
    {
        // Use the HEAD method to probe the file.
        final int status = this.getHeadMethod().getStatusCode();
        if (status == HttpURLConnection.HTTP_OK
            || status == HttpURLConnection.HTTP_BAD_METHOD /* method is bad, but resource exist */)
        {
            return FileType.FILE;
        }
        else if (status == HttpURLConnection.HTTP_NOT_FOUND
            || status == HttpURLConnection.HTTP_GONE)
        {
            return FileType.IMAGINARY;
        }
        else
        {
            throw new FileSystemException("vfs.provider.http/head.error", getName(), Integer.valueOf(status));
        }
    }

    @Override
    protected boolean doIsWriteable() throws Exception
    {
        return false;
    }

    /**
     * Lists the children of this file.
     */
    @Override
    protected String[] doListChildren() throws Exception
    {
        throw new Exception("Not implemented.");
    }

    protected String encodePath(final String decodedPath) throws URIException
    {
        return URIUtil.encodePath(decodedPath);
    }


    @Override
    protected FileContentInfoFactory getFileContentInfoFactory()
    {
        return new HttpFileContentInfoFactory();
    }

    protected boolean getFollowRedirect()
    {
        return followRedirect;
    }

    protected String getUserAgent()
    {
        return userAgent;
    }

    HeadMethod getHeadMethod() throws IOException
    {
        if (method != null)
        {
            return method;
        }
        method = new HeadMethod();
        setupMethod(method);
        final HttpClient client = getAbstractFileSystem().getClient();
        client.executeMethod(method);
        method.releaseConnection();
        return method;
    }

    protected String getUrlCharset()
    {
        return urlCharset;
    }

    /**
     * Prepares a HttpMethod object.
     *
     * @param method The object which gets prepared to access the file object.
     * @throws FileSystemException if an error occurs.
     * @throws URIException if path cannot be represented.
     * @since 2.0 (was package)
     */
    protected void setupMethod(final HttpMethod method) throws FileSystemException, URIException
    {
        final String pathEncoded = ((URLFileName) getName()).getPathQueryEncoded(this.getUrlCharset());
        method.setPath(pathEncoded);
        method.setFollowRedirects(this.getFollowRedirect());
        method.setRequestHeader("User-Agent", this.getUserAgent());
    }

    /*
    protected Map doGetAttributes() throws Exception
    {
        TreeMap map = new TreeMap();

        Header contentType = method.getResponseHeader("content-type");
        if (contentType != null)
        {
            HeaderElement[] element = contentType.getValues();
            if (element != null && element.length > 0)
            {
                map.put("content-type", element[0].getName());
            }
        }

        map.put("content-encoding", method.getResponseCharSet());
        return map;
    }
    */
}
