/*
 * 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.webdav;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.httpclient.util.DateUtil;
import org.apache.commons.vfs2.FileContentInfoFactory;
import org.apache.commons.vfs2.FileNotFolderException;
import org.apache.commons.vfs2.FileNotFoundException;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileType;
import org.apache.commons.vfs2.NameScope;
import org.apache.commons.vfs2.provider.AbstractFileName;
import org.apache.commons.vfs2.provider.DefaultFileContent;
import org.apache.commons.vfs2.provider.URLFileName;
import org.apache.commons.vfs2.provider.http.HttpFileObject;
import org.apache.commons.vfs2.util.FileObjectUtils;
import org.apache.commons.vfs2.util.MonitorOutputStream;
import org.apache.jackrabbit.webdav.DavConstants;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.MultiStatus;
import org.apache.jackrabbit.webdav.MultiStatusResponse;
import org.apache.jackrabbit.webdav.client.methods.CheckinMethod;
import org.apache.jackrabbit.webdav.client.methods.CheckoutMethod;
import org.apache.jackrabbit.webdav.client.methods.DavMethod;
import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;
import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
import org.apache.jackrabbit.webdav.client.methods.MoveMethod;
import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
import org.apache.jackrabbit.webdav.client.methods.PropPatchMethod;
import org.apache.jackrabbit.webdav.client.methods.PutMethod;
import org.apache.jackrabbit.webdav.client.methods.UncheckoutMethod;
import org.apache.jackrabbit.webdav.client.methods.VersionControlMethod;
import org.apache.jackrabbit.webdav.property.DavProperty;
import org.apache.jackrabbit.webdav.property.DavPropertyName;
import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
import org.apache.jackrabbit.webdav.property.DavPropertySet;
import org.apache.jackrabbit.webdav.property.DefaultDavProperty;
import org.apache.jackrabbit.webdav.version.DeltaVConstants;
import org.apache.jackrabbit.webdav.version.VersionControlledResource;
import org.apache.jackrabbit.webdav.xml.Namespace;
import org.w3c.dom.Node;

/**
 * A WebDAV file.
 *
 * @since 2.0
 */
public class WebdavFileObject extends HttpFileObject<WebdavFileSystem> {

    /**
     * An empty immutable {@code WebdavFileObject} array.
     */
    private static final WebdavFileObject[] EMPTY_ARRAY = new WebdavFileObject[0];

    /**
     * An OutputStream that writes to a Webdav resource.
     * <p>
     * TODO - Use piped stream to avoid temporary file.
     * </p>
     */
    private class WebdavOutputStream extends MonitorOutputStream {
        private final WebdavFileObject file;

        public WebdavOutputStream(final WebdavFileObject file) {
            super(new ByteArrayOutputStream());
            this.file = file;
        }

        private boolean createVersion(final String urlStr) {
            try {
                final VersionControlMethod method = new VersionControlMethod(urlStr);
                setupMethod(method);
                execute(method);
                return true;
            } catch (final Exception ex) {
                return false;
            }
        }

        /**
         * Called after this stream is closed.
         */
        @Override
        protected void onClose() throws IOException {
            final RequestEntity entity = new ByteArrayRequestEntity(((ByteArrayOutputStream) out).toByteArray());
            final URLFileName fileName = (URLFileName) getName();
            final String urlStr = toUrlString(fileName);
            if (builder.isVersioning(getFileSystem().getFileSystemOptions())) {
                DavPropertySet set = null;
                boolean fileExists = true;
                boolean isCheckedIn = true;
                try {
                    set = getPropertyNames(fileName);
                } catch (final FileNotFoundException fnfe) {
                    fileExists = false;
                }
                if (fileExists && set != null) {
                    if (set.contains(VersionControlledResource.CHECKED_OUT)) {
                        isCheckedIn = false;
                    } else if (!set.contains(VersionControlledResource.CHECKED_IN)) {
                        DavProperty prop = set.get(VersionControlledResource.AUTO_VERSION);
                        if (prop != null) {
                            prop = getProperty(fileName, VersionControlledResource.AUTO_VERSION);
                            if (DeltaVConstants.XML_CHECKOUT_CHECKIN.equals(prop.getValue())) {
                                createVersion(urlStr);
                            }
                        }
                    }
                }
                if (fileExists && isCheckedIn) {
                    try {
                        final CheckoutMethod checkout = new CheckoutMethod(urlStr);
                        setupMethod(checkout);
                        execute(checkout);
                        isCheckedIn = false;
                    } catch (final FileSystemException ex) {
                        log(ex);
                    }
                }

                try {
                    final PutMethod method = new PutMethod(urlStr);
                    method.setRequestEntity(entity);
                    setupMethod(method);
                    execute(method);
                    setUserName(fileName, urlStr);
                } catch (final FileSystemException ex) {
                    if (!isCheckedIn) {
                        try {
                            final UncheckoutMethod method = new UncheckoutMethod(urlStr);
                            setupMethod(method);
                            execute(method);
                            isCheckedIn = true;
                        } catch (final Exception e) {
                            // Going to throw original.
                            log(e);
                        }
                        throw ex;
                    }
                }
                if (!fileExists) {
                    createVersion(urlStr);
                    try {
                        final DavPropertySet props = getPropertyNames(fileName);
                        isCheckedIn = !props.contains(VersionControlledResource.CHECKED_OUT);
                    } catch (final FileNotFoundException fnfe) {
                        log(fnfe);
                    }
                }
                if (!isCheckedIn) {
                    final CheckinMethod checkin = new CheckinMethod(urlStr);
                    setupMethod(checkin);
                    execute(checkin);
                }
            } else {
                final PutMethod method = new PutMethod(urlStr);
                method.setRequestEntity(entity);
                setupMethod(method);
                execute(method);
                try {
                    setUserName(fileName, urlStr);
                } catch (final IOException e) {
                    // Unable to set the user name.
                    log(e);
                }
            }
            ((DefaultFileContent) this.file.getContent()).resetAttributes();
        }

        private void setUserName(final URLFileName fileName, final String urlStr) throws IOException {
            final List<DefaultDavProperty> list = new ArrayList<>();
            String name = builder.getCreatorName(getFileSystem().getFileSystemOptions());
            final String userName = fileName.getUserName();
            if (name == null) {
                name = userName;
            } else if (userName != null) {
                final String comment = "Modified by user " + userName;
                list.add(new DefaultDavProperty(DeltaVConstants.COMMENT, comment));
            }
            list.add(new DefaultDavProperty(DeltaVConstants.CREATOR_DISPLAYNAME, name));
            final PropPatchMethod method = new PropPatchMethod(urlStr, list);
            setupMethod(method);
            execute(method);
        }
    }

    /** The character set property name. */
    public static final DavPropertyName RESPONSE_CHARSET = DavPropertyName.create("response-charset");

    /** The FileSystemConfigBuilder */
    private final WebdavFileSystemConfigBuilder builder;

    private final WebdavFileSystem fileSystem;

    protected WebdavFileObject(final AbstractFileName name, final WebdavFileSystem fileSystem) {
        super(name, fileSystem, WebdavFileSystemConfigBuilder.getInstance());
        this.fileSystem = fileSystem;
        builder = (WebdavFileSystemConfigBuilder) WebdavFileSystemConfigBuilder.getInstance();
    }

    void log(Exception ex) {
        // TODO Consider logging.
    }

    protected void configureMethod(final HttpMethodBase httpMethod) {
        httpMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, WebdavMethodRetryHandler.getInstance());
    }

    /**
     * Creates this file as a folder.
     */
    @Override
    protected void doCreateFolder() throws Exception {
        final DavMethod method = new MkColMethod(toUrlString((URLFileName) getName()));
        setupMethod(method);
        try {
            execute(method);
        } catch (final FileSystemException fse) {
            throw new FileSystemException("vfs.provider.webdav/create-collection.error", getName(), fse);
        }
    }

    /**
     * Deletes the file.
     */
    @Override
    protected void doDelete() throws Exception {
        final DavMethod method = new DeleteMethod(toUrlString((URLFileName) getName()));
        setupMethod(method);
        execute(method);
    }

    /**
     * Returns the properties of the Webdav resource.
     */
    @Override
    protected Map<String, Object> doGetAttributes() throws Exception {
        final Map<String, Object> attributes = new HashMap<>();
        try {
            final URLFileName fileName = (URLFileName) getName();
            DavPropertySet properties = getProperties(fileName, DavConstants.PROPFIND_ALL_PROP,
                    new DavPropertyNameSet(), false);
            @SuppressWarnings("unchecked") // iterator() is documented to return DavProperty instances
            final Iterator<DavProperty> iter = properties.iterator();
            while (iter.hasNext()) {
                final DavProperty property = iter.next();
                attributes.put(property.getName().toString(), property.getValue());
            }
            properties = getPropertyNames(fileName);
            @SuppressWarnings("unchecked") // iterator() is documented to return DavProperty instances
            final Iterator<DavProperty> iter2 = properties.iterator();
            while (iter2.hasNext()) {
                DavProperty property = iter2.next();
                if (!attributes.containsKey(property.getName().getName())) {
                    property = getProperty(fileName, property.getName());
                    if (property != null) {
                        final Object name = property.getName();
                        final Object value = property.getValue();
                        if (name != null && value != null) {
                            attributes.put(name.toString(), value);
                        }
                    }
                }
            }
            return attributes;
        } catch (final Exception e) {
            throw new FileSystemException("vfs.provider.webdav/get-attributes.error", getName(), e);
        }
    }

    /**
     * Returns the size of the file content (in bytes).
     */
    @Override
    protected long doGetContentSize() throws Exception {
        final DavProperty property = getProperty((URLFileName) getName(), DavConstants.PROPERTY_GETCONTENTLENGTH);
        if (property != null) {
            final String value = (String) property.getValue();
            return Long.parseLong(value);
        }
        return 0;
    }

    /**
     * Returns the last modified time of this file. Is only called if {@link #doGetType} does not return
     * {@link FileType#IMAGINARY}.
     */
    @Override
    protected long doGetLastModifiedTime() throws Exception {
        final DavProperty property = getProperty((URLFileName) getName(), DavConstants.PROPERTY_GETLASTMODIFIED);
        if (property != null) {
            final String value = (String) property.getValue();
            return DateUtil.parseDate(value).getTime();
        }
        return 0;
    }

    @Override
    protected OutputStream doGetOutputStream(final boolean bAppend) throws Exception {
        return new WebdavOutputStream(this);
    }

    /**
     * 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 {
        try {
            return isDirectory((URLFileName) getName()) ? FileType.FOLDER : FileType.FILE;
        } catch (final FileNotFolderException | FileNotFoundException fnfe) {
            return FileType.IMAGINARY;
        }

    }

    /**
     * Determines if this file can be written to. Is only called if {@link #doGetType} does not return
     * {@link FileType#IMAGINARY}.
     * <p>
     * This implementation always returns true.
     *
     * @return true if the file is writable.
     * @throws Exception if an error occurs.
     */
    @Override
    protected boolean doIsWriteable() throws Exception {
        return true;
    }

    /**
     * Lists the children of the file.
     */
    @Override
    protected String[] doListChildren() throws Exception {
        // use doListChildrenResolved for performance
        return null;
    }

    /**
     * Lists the children of the file.
     */
    @Override
    protected FileObject[] doListChildrenResolved() throws Exception {
        PropFindMethod method = null;
        try {
            final URLFileName name = (URLFileName) getName();
            if (isDirectory(name)) {
                final DavPropertyNameSet nameSet = new DavPropertyNameSet();
                nameSet.add(DavPropertyName.create(DavConstants.PROPERTY_DISPLAYNAME));

                method = new PropFindMethod(toUrlString(name), nameSet, DavConstants.DEPTH_1);

                execute(method);
                final List<WebdavFileObject> vfs = new ArrayList<>();
                if (method.succeeded()) {
                    final MultiStatusResponse[] responses = method.getResponseBodyAsMultiStatus().getResponses();

                    for (final MultiStatusResponse response : responses) {
                        if (isCurrentFile(response.getHref(), name)) {
                            continue;
                        }
                        final String resourceName = resourceName(response.getHref());
                        if (resourceName != null && !resourceName.isEmpty()) {
                            final WebdavFileObject fo = (WebdavFileObject) FileObjectUtils.getAbstractFileObject(
                                    getFileSystem().resolveFile(getFileSystem().getFileSystemManager()
                                            .resolveName(getName(), resourceName, NameScope.CHILD)));
                            vfs.add(fo);
                        }
                    }
                }
                return vfs.toArray(EMPTY_ARRAY);
            }
            throw new FileNotFolderException(getName());
        } catch (final FileNotFolderException fnfe) {
            throw fnfe;
        } catch (final DavException | IOException e) {
            throw new FileSystemException(e.getMessage(), e);
        } finally {
            if (method != null) {
                method.releaseConnection();
            }
        }
    }

    /**
     * Rename the file.
     */
    @Override
    protected void doRename(final FileObject newFile) throws Exception {
        final String url = encodePath(toUrlString((URLFileName) getName()));
        final String dest = toUrlString((URLFileName) newFile.getName(), false);
        final DavMethod method = new MoveMethod(url, dest, false);
        setupMethod(method);
        execute(method);
    }

    /**
     * Sets an attribute of this file. Is only called if {@link #doGetType} does not return {@link FileType#IMAGINARY}.
     */
    @Override
    protected void doSetAttribute(final String attrName, final Object value) throws Exception {
        try {
            final URLFileName fileName = (URLFileName) getName();
            final String urlStr = toUrlString(fileName);
            final DavPropertySet properties = new DavPropertySet();
            final DavPropertyNameSet propertyNameSet = new DavPropertyNameSet();
            final DavProperty property = new DefaultDavProperty(attrName, value, Namespace.EMPTY_NAMESPACE);
            if (value != null) {
                properties.add(property);
            } else {
                propertyNameSet.add(property.getName()); // remove property
            }

            final PropPatchMethod method = new PropPatchMethod(urlStr, properties, propertyNameSet);
            setupMethod(method);
            execute(method);
            if (!method.succeeded()) {
                throw new FileSystemException("Property '" + attrName + "' could not be set.");
            }
        } catch (final FileSystemException fse) {
            throw fse;
        } catch (final Exception e) {
            throw new FileSystemException("vfs.provider.webdav/set-attributes", e, getName(), attrName);
        }
    }

    /**
     * Execute a 'Workspace' operation.
     *
     * @param method The DavMethod to invoke.
     * @throws FileSystemException If an error occurs.
     */
    private void execute(final DavMethod method) throws FileSystemException {
        try {
            final int status = fileSystem.getClient().executeMethod(method);
            if (status == HttpURLConnection.HTTP_NOT_FOUND || status == HttpURLConnection.HTTP_GONE) {
                throw new FileNotFoundException(method.getURI());
            }
            method.checkSuccess();
        } catch (final FileSystemException fse) {
            throw fse;
        } catch (final IOException e) {
            throw new FileSystemException(e);
        } catch (final DavException e) {
            throw ExceptionConverter.generate(e);
        } finally {
            if (method != null) {
                method.releaseConnection();
            }
        }
    }

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

    DavPropertySet getProperties(final URLFileName name) throws FileSystemException {
        return getProperties(name, DavConstants.PROPFIND_ALL_PROP, new DavPropertyNameSet(), false);
    }

    DavPropertySet getProperties(final URLFileName name, final DavPropertyNameSet nameSet, final boolean addEncoding)
            throws FileSystemException {
        return getProperties(name, DavConstants.PROPFIND_BY_PROPERTY, nameSet, addEncoding);
    }

    DavPropertySet getProperties(final URLFileName name, final int type, final DavPropertyNameSet nameSet,
            final boolean addEncoding) throws FileSystemException {
        try {
            final String urlStr = toUrlString(name);
            final PropFindMethod method = new PropFindMethod(urlStr, type, nameSet, DavConstants.DEPTH_0);
            setupMethod(method);
            execute(method);
            if (method.succeeded()) {
                final MultiStatus multiStatus = method.getResponseBodyAsMultiStatus();
                final MultiStatusResponse response = multiStatus.getResponses()[0];
                final DavPropertySet props = response.getProperties(HttpStatus.SC_OK);
                if (addEncoding) {
                    final DavProperty prop = new DefaultDavProperty(RESPONSE_CHARSET, method.getResponseCharSet());
                    props.add(prop);
                }
                return props;
            }
            return new DavPropertySet();
        } catch (final FileSystemException fse) {
            throw fse;
        } catch (final Exception e) {
            throw new FileSystemException("vfs.provider.webdav/get-property.error", e, getName(), name, type,
                    nameSet.getContent(), addEncoding);
        }
    }

    DavProperty getProperty(final URLFileName fileName, final DavPropertyName name) throws FileSystemException {
        final DavPropertyNameSet nameSet = new DavPropertyNameSet();
        nameSet.add(name);
        final DavPropertySet propertySet = getProperties(fileName, nameSet, false);
        return propertySet.get(name);
    }

    DavProperty getProperty(final URLFileName fileName, final String property) throws FileSystemException {
        return getProperty(fileName, DavPropertyName.create(property));
    }

    DavPropertySet getPropertyNames(final URLFileName name) throws FileSystemException {
        return getProperties(name, DavConstants.PROPFIND_PROPERTY_NAMES, new DavPropertyNameSet(), false);
    }

    /**
     * Convert the FileName to an encoded url String.
     *
     * @param name The FileName.
     * @return The encoded URL String.
     */
    private String hrefString(final URLFileName name) {
        final URLFileName newFile = new URLFileName("http", name.getHostName(), name.getPort(), name.getDefaultPort(),
                null, null, name.getPath(), name.getType(), name.getQueryString());
        try {
            return newFile.getURIEncoded(this.getUrlCharset());
        } catch (final Exception e) {
            return name.getURI();
        }
    }

    private boolean isCurrentFile(final String href, final URLFileName fileName) {
        String name = hrefString(fileName);
        if (href.endsWith("/") && !name.endsWith("/")) {
            name += "/";
        }
        return href.equals(name) || href.equals(fileName.getPath());
    }

    private boolean isDirectory(final URLFileName name) throws IOException {
        try {
            final DavProperty property = getProperty(name, DavConstants.PROPERTY_RESOURCETYPE);
            final Node node;
            if (property != null && (node = (Node) property.getValue()) != null) {
                return node.getLocalName().equals(DavConstants.XML_COLLECTION);
            }
            return false;
        } catch (final FileNotFoundException fse) {
            throw new FileNotFolderException(name);
        }
    }

    /**
     * Returns the resource name from the path.
     *
     * @param path the path to the file.
     * @return The resource name
     */
    private String resourceName(String path) {
        if (path.endsWith("/")) {
            path = path.substring(0, path.length() - 1);
        }
        final int i = path.lastIndexOf("/");
        return i >= 0 ? path.substring(i + 1) : path;
    }

    /**
     * Prepares a Method object.
     *
     * @param method the HttpMethod.
     * @throws FileSystemException if an error occurs encoding the uri.
     * @throws URIException if the URI is in error.
     */
    @Override
    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", "Jakarta-Commons-VFS");
        method.addRequestHeader("Cache-control", "no-cache");
        method.addRequestHeader("Cache-store", "no-store");
        method.addRequestHeader("Pragma", "no-cache");
        method.addRequestHeader("Expires", "0");
    }

    private String toUrlString(final URLFileName name) {
        return toUrlString(name, true);
    }

    /**
     * Converts the given URLFileName to an encoded URL String.
     *
     * @param name The FileName.
     * @param includeUserInfo true if user information should be included.
     * @return The encoded URL String.
     */
    private String toUrlString(final URLFileName name, final boolean includeUserInfo) {
        String user = null;
        String password = null;
        if (includeUserInfo) {
            user = name.getUserName();
            password = name.getPassword();
        }
        final URLFileName newFile = new URLFileName("http", name.getHostName(), name.getPort(), name.getDefaultPort(),
                user, password, name.getPath(), name.getType(), name.getQueryString());
        try {
            return newFile.getURIEncoded(this.getUrlCharset());
        } catch (final Exception e) {
            return name.getURI();
        }
    }
}
