package com.jscape.inet.scp;

import com.jscape.util.service.Service;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * @author Alex Usun
 */
public interface FileService
        extends Service<Void> {

    boolean available();

    Long readFile(String sourcePath,
                  OutputStream destination,
                  boolean fileAttributesPreservingRequired,
                  TransferListener listener)
            throws OperationException;

    void readFiles(String wildcard, File directory, boolean fileAttributesPreservingRequired, TransferListener listener)
            throws OperationException;

    void readDirectory(String sourcePath, File destination, boolean fileAttributesPreservingRequired, TransferListener listener)
            throws OperationException;

    void writeFile(InputStream source,
                   String destinationPath,
                   String destinationName,
                   long lengthBytes,
                   String mode,
                   Long modificationDate,
                   TransferListener listener)
            throws OperationException;

    void writeDirectory(File source, String destinationPath, String destinationName, String mode, boolean fileAttributesPreservingRequired, TransferListener listener)
            throws OperationException;

    void cancelTransferOperation();

    class OperationException
            extends ServiceException {

        private static final long serialVersionUID = -8933434214070929148L;

        public static OperationException wrap(Throwable e) {
            return e instanceof OperationException ? (OperationException) e : new OperationException(e);
        }

        public OperationException() {
        }

        public OperationException(String message) {
            super(message);
        }

        public OperationException(String message, Throwable cause) {
            super(message, cause);
        }

        public OperationException(Throwable cause) {
            super(cause.getMessage() != null ? cause.getMessage() : cause.toString(), cause);
        }
    }

    interface TransferListener {

        TransferListener NULL = new TransferListener() {

            @Override
            public void onTransferStarted(String filename, long totalBytes) {
            }

            @Override
            public void onTransferProgress(long transferredBytes) {
            }

            @Override
            public void onTransferCompleted(long totalBytes) {
            }
        };

        void onTransferStarted(String filename, long totalBytes);

        void onTransferProgress(long transferredBytes);

        void onTransferCompleted(long totalBytes);
    }

}
