package com.avg.zaap.crashlibrary.publish.packer;

import android.support.annotation.NonNull;

import java.util.ArrayList;

/**
 * Interface for packing to binary file.
 * Created by marek.osvald on 15.4.2016.
 */
public interface IBinPacker {

    /**
     * Custom file extension for packed files.
     */
    String EXT_RESULT = ".bp";

    /**
     * Grab file from given path, pack it to .bp file that is stored on predefined location (see constructors).
     *
     * @param filePath  of source file, consists of absolute path (extension needed!).
     * @param forceMode decides if outputFolderName overwrite existing file or create new one with incremented name.
     * @return destination file path of created .bp file.
     * @throws BinPackerException when given file cannot be packed.
     */
    String packFile(@NonNull final String filePath, boolean forceMode) throws BinPackerException;

    /**
     * Grab folder from given path, pack it to .bp file that is stored on predefined location (see constructors).
     * NOTE: empty folders will be ignored.
     *
     * @param folderPath of source file, consists of absolute path.
     * @param forceMode  decides if outputFolderName overwrite existing file or create new one with incremented name.
     * @return destination file path of created .bp file.
     * @throws BinPackerException when given folder cannot be packed.
     */
    String packFolder(@SuppressWarnings("SameParameterValue") @NonNull final String folderPath, @SuppressWarnings("SameParameterValue") boolean forceMode) throws BinPackerException;

    /**
     * Process given paths as all folders/files be in same root directory with name {@code outputFolderName}.
     *
     * @param outputFolderName name of final {@link BinPacker#EXT_RESULT} file.
     * @param paths            list of dirs/files to pack into {@code outputFolderName}.
     * @param forceMode        decides if outputFolderName overwrite existing file or create new one with incremented name.
     * @return path where final file is stored.
     * @throws BinPackerException when given list of files cannot be packed.
     */
    String packAll(String outputFolderName, @NonNull ArrayList<String> paths, boolean forceMode) throws BinPackerException;

    /**
     * Calls {@link IBinPacker#packAll(String, ArrayList, boolean)}.
     *
     * @param outputFolderName name of final {@link BinPacker#EXT_RESULT} file.
     * @param forceMode        decides if outputFolderName overwrite existing file or create new one with incremented name.
     * @param paths            array of dirs/files to pack into {@code outputFolderName}.
     * @return path where final file is stored.
     * @throws BinPackerException when given array of files cannot be packed.
     */
    String packAll(@SuppressWarnings("SameParameterValue") String outputFolderName, @SuppressWarnings("SameParameterValue") boolean forceMode, String... paths) throws BinPackerException;

    /**
     * For one file/dir/array set output name call correct method.
     *
     * @param forceMode decides if should overwrite existing files.
     * @param fileName  output file name
     * @param paths     with one or more paths to pack into one archive.
     * @return path to the archive.
     * @throws BinPackerException when given array of files cannot be packed.
     */
    String pack(@SuppressWarnings("SameParameterValue") boolean forceMode, @NonNull String fileName, @NonNull String... paths) throws BinPackerException;

    /**
     * For one file/dir/array set output name call correct method.
     *
     * @param fileName output file name
     * @param paths    with one or more paths to pack into one archive.
     * @return path to the archive.
     * @throws BinPackerException when given pats cannot be packed
     */
    String pack(@NonNull String fileName, @NonNull String... paths) throws BinPackerException;

    /**
     * Custom exception for inner usage.
     */
    class BinPackerException extends Exception {
        /**
         * Default constructor. Calls {@link RuntimeException} constructor.
         */
        public BinPackerException() {
            super();
        }

        /**
         * Parametric constructor. Initializes the exception with a detailed message.
         *
         * @param detailMessage detailed message to initialize the exception with
         */
        public BinPackerException(String detailMessage) {
            super(detailMessage);
        }

        /**
         * Parametric constructor. Initializes the exception with a detailed message and a throwable
         * instance.
         *
         * @param detailMessage detailed message to initialize the exception with
         * @param throwable     throwable instance to initialize the exception with
         */
        @SuppressWarnings("unused")
        public BinPackerException(String detailMessage, Throwable throwable) {
            super(detailMessage, throwable);
        }

        /**
         * Parametric constructor. Initializes the exception with a throwable instance.
         *
         * @param throwable throwable instance to initialize the exception with
         */
        public BinPackerException(Throwable throwable) {
            super(throwable);
        }
    }
}
