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

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.security.cert.Certificate;
import java.util.Arrays;
import java.util.Map;

import org.apache.commons.vfs2.provider.AbstractFileObject;
import org.apache.commons.vfs2.util.RandomAccessMode;

/**
 * Represents the data content of a file.
 * <p>
 * To read from a file, use the {@code InputStream} returned by {@link #getInputStream()}.
 * </p>
 * <p>
 * To write to a file, use the {@code OutputStream} returned by {@link #getOutputStream()} method. This will create the
 * file, and the parent folder, if necessary.
 * </p>
 * <p>
 * A file may have multiple InputStreams open at the same time.
 * </p>
 *
 * @see FileObject#getContent
 * @since 2.2
 */
public interface FileContent extends Closeable {

    /**
     * Closes all resources used by the content, including any open stream. Commits pending changes to the file.
     * <p>
     * This method is a hint to the implementation that it can release resources. This object can continue to be used
     * after calling this method.
     * </p>
     *
     * @throws FileSystemException if an error occurs closing the file.
     */
    @Override
    void close() throws FileSystemException;

    /**
     * Gets the value of an attribute of the file's content.
     *
     * @param attrName The name of the attribute. Attribute names are case insensitive.
     * @return The value of the attribute, or null if the attribute value is unknown.
     * @throws FileSystemException If the file does not exist, or does not support attributes.
     */
    Object getAttribute(String attrName) throws FileSystemException;

    /**
     * Gets the attributes of the file's content.
     *
     * @return The names of the attributes. Never returns null;
     * @throws FileSystemException If the file does not exist, or does not support attributes.
     */
    String[] getAttributeNames() throws FileSystemException;

    /**
     * Returns a read-only map of this file's attributes.
     *
     * @return The attribute Map.
     * @throws FileSystemException If the file does not exist, or does not support attributes.
     */
    Map<String, Object> getAttributes() throws FileSystemException;

    /**
     * Returns the content of a file as a byte array.
     *
     * @return The content as a byte array.
     * @throws IOException if the file content cannot be accessed.
     * @since 2.4
     */
    default byte[] getByteArray() throws IOException {
        final long sizeL = getSize();
        if (sizeL > Integer.MAX_VALUE) {
            throw new IllegalStateException(String.format("File content is too large for a byte array: %,d", sizeL));
        }
        final boolean sizeUndefined = sizeL < 0;
        final int size = sizeUndefined ? AbstractFileObject.DEFAULT_BUFFER_SIZE : (int) sizeL;
        final byte[] buf = new byte[size];
        int pos;
        try (final InputStream in = getInputStream(size)) {
            int read = 0;
            for (pos = 0; pos < size && read >= 0; pos += read) {
                read = in.read(buf, pos, size - pos);
            }
        }
        return sizeUndefined && pos < buf.length ? Arrays.copyOf(buf, ++pos) : buf;
    }

    /**
     * Gets the certificates if any used to sign this file or folder.
     *
     * @return The certificates, or an empty array if there are no certificates or the file does not support signing.
     * @throws FileSystemException If the file does not exist, or is being written.
     */
    Certificate[] getCertificates() throws FileSystemException;

    /**
     * Gets the content info. e.g. type, encoding, ...
     *
     * @return the FileContentInfo
     * @throws FileSystemException if an error occurs.
     */
    FileContentInfo getContentInfo() throws FileSystemException;

    /**
     * Gets the file which this is the content of.
     *
     * @return The FileObject this is the content of.
     */
    FileObject getFile();

    /**
     * Gets an input stream for reading the file's content.
     * <p>
     * There may only be a single input or output stream open for the file at any time.
     * </p>
     *
     * @return An input stream to read the file's content from. The input stream is buffered, so there is no need to
     *         wrap it in a {@code BufferedInputStream}.
     * @throws FileSystemException If the file does not exist, or is being read, or is being written, or on error
     *         opening the stream.
     */
    InputStream getInputStream() throws FileSystemException;

    /**
     * Gets an input stream for reading the file's content.
     * <p>
     * There may only be a single input or output stream open for the file at any time.
     * </p>
     *
     * @param bufferSize The buffer size to use.
     * @return An input stream to read the file's content from. The input stream is buffered, so there is no need to
     *         wrap it in a {@code BufferedInputStream}.
     * @throws FileSystemException If the file does not exist, or is being read, or is being written, or on error
     *         opening the stream.
     * @since 2.4
     */
    default InputStream getInputStream(final int bufferSize) throws FileSystemException {
        return getInputStream();
    }

    /**
     * Gets the last-modified timestamp of the file.
     *
     * @return The last-modified timestamp.
     * @throws FileSystemException If the file does not exist, or is being written to, or on error determining the
     *         last-modified timestamp.
     */
    long getLastModifiedTime() throws FileSystemException;

    /**
     * Gets an output stream for writing the file's content.
     * <p>
     * If the file does not exist, this method creates it, and the parent folder, if necessary. If the file does exist,
     * it is replaced with whatever is written to the output stream.
     * </p>
     * <p>
     * There may only be a single input or output stream open for the file at any time.
     * </p>
     *
     * @return An output stream to write the file's content to. The stream is buffered, so there is no need to wrap it
     *         in a {@code BufferedOutputStream}.
     * @throws FileSystemException If the file is read-only, or is being read, or is being written, or on error opening
     *         the stream.
     */
    OutputStream getOutputStream() throws FileSystemException;

    /**
     * Gets an output stream for writing the file's content.
     * <p>
     * If the file does not exist, this method creates it, and the parent folder, if necessary. If the file does exist,
     * it is replaced with whatever is written to the output stream.
     * </p>
     * <p>
     * There may only be a single input or output stream open for the file at any time.
     * </p>
     *
     * @param bAppend true if you would like to append to the file. This may not be supported by all implementations.
     * @return An output stream to write the file's content to. The stream is buffered, so there is no need to wrap it
     *         in a {@code BufferedOutputStream}.
     * @throws FileSystemException If the file is read-only, or is being read, or is being written, or bAppend is true
     *         and the implementation does not support it, or on error opening the stream.
     */
    OutputStream getOutputStream(boolean bAppend) throws FileSystemException;

    /**
     * Gets an output stream for writing the file's content.
     * <p>
     * If the file does not exist, this method creates it, and the parent folder, if necessary. If the file does exist,
     * it is replaced with whatever is written to the output stream.
     * </p>
     * <p>
     * There may only be a single input or output stream open for the file at any time.
     * </p>
     *
     * @param bAppend true if you would like to append to the file. This may not be supported by all implementations.
     * @param bufferSize The buffer size to use.
     * @return An output stream to write the file's content to. The stream is buffered, so there is no need to wrap it
     *         in a {@code BufferedOutputStream}.
     * @throws FileSystemException If the file is read-only, or is being read, or is being written, or bAppend is true
     *         and the implementation does not support it, or on error opening the stream.
     * @since 2.4
     */
    default OutputStream getOutputStream(final boolean bAppend, final int bufferSize) throws FileSystemException {
        return getOutputStream(bAppend);
    }

    /**
     * Gets an output stream for writing the file's content.
     * <p>
     * If the file does not exist, this method creates it, and the parent folder, if necessary. If the file does exist,
     * it is replaced with whatever is written to the output stream.
     * </p>
     * <p>
     * There may only be a single input or output stream open for the file at any time.
     * </p>
     *
     * @param bufferSize The buffer size to use.
     * @return An output stream to write the file's content to. The stream is buffered, so there is no need to wrap it
     *         in a {@code BufferedOutputStream}.
     * @throws FileSystemException If the file is read-only, or is being read, or is being written, or bAppend is true
     *         and the implementation does not support it, or on error opening the stream.
     * @since 2.4
     */
    default OutputStream getOutputStream(final int bufferSize) throws FileSystemException {
        return getOutputStream();
    }

    /**
     * Gets an stream for reading/writing the file's content.
     * <p>
     * If the file does not exist, and you use one of the write* methods, this method creates it, and the parent folder,
     * if necessary. If the file does exist, parts of the file are replaced with whatever is written at a given
     * position.
     * </p>
     * <p>
     * There may only be a single input or output stream open for the file at any time.
     * </p>
     *
     * @param mode The mode to use to access the file.
     * @return the stream for reading and writing the file's content.
     * @throws FileSystemException If the file is read-only, or is being read, or is being written, or on error opening
     *         the stream.
     */
    RandomAccessContent getRandomAccessContent(final RandomAccessMode mode) throws FileSystemException;

    /**
     * Gets the size of the file, in bytes.
     *
     * @return The size of the file, in bytes.
     * @throws FileSystemException If the file does not exist, or is being written to, or on error determining the size.
     */
    long getSize() throws FileSystemException;

    /**
     * Returns the content of a file as a String.
     *
     * @param charset The file character set, may be null.
     * @return The content as a byte array.
     * @throws IOException if the file content cannot be accessed.
     * @since 2.4
     */
    default String getString(final Charset charset) throws IOException {
        return new String(getByteArray(), charset == null ? Charset.defaultCharset() : charset);
    }

    /**
     * Gets the content of a file as a String.
     *
     * @param charset The file character set, may be null.
     * @return The content as a byte array.
     * @throws IOException if the file content cannot be accessed.
     * @since 2.4
     */
    default String getString(final String charset) throws IOException {
        return new String(getByteArray(), charset == null ? Charset.defaultCharset().name() : charset);
    }

    /**
     * Checks if an attribute of the file's content exists.
     *
     * @param attrName The name of the attribute.
     * @return true if the attribute exists, false otherwise.
     * @throws FileSystemException If the file does not exist, or does not support attributes.
     */
    boolean hasAttribute(String attrName) throws FileSystemException;

    /**
     * Checks if the receiver is empty.
     *
     * @return true if the receiver is empty, false otherwise.
     * @throws FileSystemException If the file does not exist, or is being written to, or on error determining the size.
     * @since 2.5.0
     */
    default boolean isEmpty() throws FileSystemException {
        return getSize() <= 0;
    }

    /**
     * Checks if this file has open streams.
     *
     * @return true if the file is open, false otherwise.
     */
    boolean isOpen();

    /**
     * Removes the value of an attribute of the file's content.
     *
     * @param attrName The name of the attribute.
     * @throws FileSystemException If the file does not exist, or is read-only, or does not support attributes, or on
     *         error removing the attribute.
     */
    void removeAttribute(String attrName) throws FileSystemException;

    /**
     * Sets the value of an attribute of the file's content. Creates the file if it does not exist.
     *
     * @param attrName The name of the attribute.
     * @param value The value of the attribute.
     * @throws FileSystemException If the file does not exist, or is read-only, or does not support attributes, or on
     *         error setting the attribute.
     */
    void setAttribute(String attrName, Object value) throws FileSystemException;

    /**
     * Sets the last-modified timestamp of the file. Creates the file if it does not exist.
     *
     * @param modTime The time to set the last-modified timestamp to.
     * @throws FileSystemException If the file is read-only, or is being written to, or on error setting the
     *         last-modified timestamp.
     */
    void setLastModifiedTime(long modTime) throws FileSystemException;

    /**
     * Writes this content to another FileContent.
     *
     * @param output The target OutputStream.
     * @throws IOException if an error occurs writing the content.
     * @return the total number of bytes written
     * @since 2.1
     */
    long write(FileContent output) throws IOException;

    /**
     * Writes this content to another FileObject.
     *
     * @param file The target FileObject.
     * @throws IOException if an error occurs writing the content.
     * @return the total number of bytes written
     * @since 2.1
     */
    long write(FileObject file) throws IOException;

    /**
     * Writes this content to an OutputStream.
     *
     * @param output The target OutputStream.
     * @return the total number of bytes written
     * @throws IOException if an error occurs writing the content.
     * @since 2.1
     */
    long write(OutputStream output) throws IOException;

    /**
     * Writes this content to an OutputStream.
     *
     * @param output The target OutputStream.
     * @param bufferSize The buffer size to write data chunks.
     * @return the total number of bytes written
     * @throws IOException if an error occurs writing the file.
     * @since 2.1
     */
    long write(OutputStream output, int bufferSize) throws IOException;

}
