"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = require("events");
const types_1 = require("./types");
const Validate_1 = __importDefault(require("../Validate/Validate"));
const EVENT_STORAGE_UNITS_CHANGED = 'storage_units_changed';
/**
 * The `sos.fileSystem` API groups together methods for low-level access to the file system. The File System API supports both internal and
 * external storage.
 *
 * :::warning Differences between File System API and Offline Cache API
 * File System directory structure is **PERSISTENT** and is **NOT** automatically deleted through `Applet Reload` power action!
 * Applet Reload only deletes `/data` directory which is reserved for simplified [Offline Cache API](./offline). Use
 * `deleteFile()` to clear the device storage file system.
 * :::
 *
 * :::info GitHub Example
 * - [Example usage of File System API in Applet](https://github.com/signageos/applet-examples/tree/master/examples/content-js-api/file-system)
 * :::
 *
 * <details>
 *     <summary>Device File System Capabilities</summary>
 * 		| Capability | Description |
 * 		|:------------|:-------------|
 * 		| `FILE_SYSTEM_INTERNAL_STORAGE` | If device supports internal storage units |
 * 	 	| `FILE_SYSTEM_EXTERNAL_STORAGE` | If device supports connecting external storage units |
 * 		| `FILE_SYSTEM_FILE_CHECKSUM` | If device supports checksum for MD5 or CRC32 hash algorithms |
 * 		| `FILE_SYSTEM_LINK` | If device supports creating hard links to files |
 * 		| `FILE_SYSTEM_CREATE_ARCHIVE` | If device supports creating archives - zip |
 * 		| `FILE_SYSTEM_ARCHIVE_EXTRACT_INFO` | If device supports extracting information about archive files |
 *
 * 		If you want to check if the device supports this capability, use [`sos.display.supports()`](https://developers.signageos.io/sdk/sos/display#supports).
 * </details>
 *
 *
 * ## Storing files permanently
 * To allow more low-level file operations, the applet SDK exposes the File System API. Files created using this API are permanent and are only removed on a factory reset or file system wipeout.
 * The file system is also shared between all applets, which means you cannot rely on any file system structure on startup because a different applet on the device could have saved files you didn't expect.
 * To mitigate this issue, create a directory for your applet and save all files inside it.
 *
 * @example
 * import sos from '@signageos/front-applet';
 *
 * sos.onReady(async () => {
 * 	const storageUnits = await sos.fileSystem.listStorageUnits();
 * 	const rootPath = {
 * 		filePath: '', // Empty string is used as an absolute path instead of "/"
 * 		storageUnit: storageUnits.find((s) => !s.removable), // Find internal storage
 * 	};
 *
 * 	// This will return files previous applets saved to the device
 * 	const files = await sos.fileSystem.listFiles(rootPath);
 * });
 */
class FileSystem {
    messagePrefix;
    postMessage;
    static MESSAGE_PREFIX = 'file_system';
    eventEmitter;
    /** @internal */
    constructor(messagePrefix, postMessage) {
        this.messagePrefix = messagePrefix;
        this.postMessage = postMessage;
        this.eventEmitter = new events_1.EventEmitter();
    }
    /**
     * The `listStorageUnits()` method lists all available storage units. All devices always have one internal storage device (with
     * `removable: false`) and zero or more external devices. The capacity values are in bytes.
     *
     * :::note
     * This is a mandatory method that is required for all the other File System APIs. The other APIs require a storageUnit object that is retrieved from this method to manipulate with files on a correct storage location (internal/external).
     * :::
     *
     * :::warning
     * `storageUnit` is a dynamic object! It has to be always generated and retrieved by this JS API, as the values in type differ platform by platform. Never generate the object manually. `{"type":"internal"}` is for demonstration only.
     * :::
     *
     * @returns {Promise<IStorageUnit[]>} An array of storage units available on the device.
     * @throws InternalFileSystemError Unexpected error occurred when listing storage units.
     * @since 2.1.0
     *
     * @example
     * // Storage units are equivalent to disk volumes (C:, D: etc on Windows; /mnt/disc1, /mnt/disc2 on Unix)
     * const storageUnits = await sos.fileSystem.listStorageUnits();
     * const externalStorageUnits = storageUnits.filter((storageUnit) => storageUnit.removable);
     * externalStorageUnits.forEach((storageUnit) => {
     *  console.log(`Storage Unit Type: ${storageUnit.type}`);
     *	console.log(`Capacity: ${storageUnit.capacity} bytes`);
     * });
     */
    async listStorageUnits() {
        const { storageUnits } = await this.postMessage({
            type: this.getMessage('list_storage_units'),
        });
        return storageUnits;
    }
    /**
     * A shorthand method for listing only the internal storage units (i.e., those with the `removable: false`). The capacity values are in bytes.
     *
     * @returns {Promise<IStorageUnit[]>} An array of internal storage units available on the device.
     * @since 7.0.0
     *
     * @example
     * // List internal storage units
     * const internalStorageUnits = await sos.fileSystem.listInternalStorageUnits();
     * internalStorageUnits.forEach((storageUnit) => {
     *   console.log(`Storage Unit Type: ${storageUnit.type}`);
     *   console.log(`Capacity: ${storageUnit.capacity} bytes`);
     *   console.log(`Free Space: ${storageUnit.freeSpace} bytes`);
     *   console.log(`Usable Space: ${storageUnit.usableSpace} bytes`);
     * });
     */
    async listInternalStorageUnits() {
        const allStorageUnits = await this.listStorageUnits();
        return allStorageUnits.filter((storageUnit) => !storageUnit.removable);
    }
    /**
     * The `onStorageUnitsChanged()` method sets up a listener, which is called whenever the list of storage units changes.
     *
     * @param listener The listener function to be called when the storage units change.
     * @throws Error If `listener` is not a valid function.
     * @since 2.1.0
     */
    onStorageUnitsChanged(listener) {
        (0, Validate_1.default)({ listener }).required().function();
        this.eventEmitter.addListener(EVENT_STORAGE_UNITS_CHANGED, listener);
    }
    /**
     * The `removeStorageUnitsChangedListener()` method removes a listener, previously added by `onStorageUnitsChanged()`
     */
    removeStorageUnitsChangedListener(listener) {
        (0, Validate_1.default)({ listener }).required().function();
        this.eventEmitter.removeListener(EVENT_STORAGE_UNITS_CHANGED, listener);
    }
    /**
     * The `removeAllListeners()` method removes all listeners, previously added by `onStorageUnitsChanged()`
     */
    removeAllListeners() {
        this.eventEmitter.removeAllListeners(EVENT_STORAGE_UNITS_CHANGED);
    }
    /**
     * The `listFiles()` method lists all files and directories in the specified path (nested files are not included).
     *
     * @param directoryPath The path to the directory where files will be listed.
     * @returns {Promise<IFilePath[]>} A promise that resolves to an array of file paths in the specified directory.
     * @throws Error If `directoryPath` is not a valid object or does not contain `storageUnit` and `filePath`.
     * @throws Error If the path does not exist, or it is a file.
     * @since 2.1.0
     *
     * @example
     * // List files in the root directory of the internal storage unit
     * const internalStorageUnit = (await sos.fileSystem.listInternalStorageUnits())[0];
     * const directoryPath = {
     * 	storageUnit: internalStorageUnit,
     * 	filePath: '', // Empty string is used as an absolute path instead of "/"
     * };
     *
     * const files = await sos.fileSystem.listFiles(directoryPath);
     * console.log('Files in the root directory:', files.length);
     * files.forEach((file) => {
     * 	console.log(`File: ${file.filePath}`);
     * });
     */
    async listFiles(directoryPath) {
        (0, Validate_1.default)({ directoryPath }).required().object(types_1.VIFilePath);
        const { files } = await this.postMessage({
            type: this.getMessage('list_files'),
            directoryPath,
        });
        return files;
    }
    /**
     * The `exists()` method checks whether a file or directory exists.
     *
     * @param filePath The path to the file or directory to check.
     * @returns {Promise<boolean>} A promise that resolves to `true` if the file or directory exists, `false` otherwise.
     * @throws Error If the `filePath` is not a valid object or does not contain `storageUnit` and `filePath`.
     * @throws Error If any error occurs during the existence check operation on the device.
     * @since 2.1.0
     *
     * @example
     * const filePath = {
     * 	storageUnit: internalStorageUnit,
     * 	filePath: 'path/to/file.txt',
     * };
     *
     * const fileExists = await sos.fileSystem.exists(filePath);
     * console.log(`File exists: ${fileExists}`); // Prints true if the file exists, false otherwise
     */
    async exists(filePath) {
        (0, Validate_1.default)({ filePath }).required().object(types_1.VIFilePath);
        const { exists } = await this.postMessage({
            type: this.getMessage('exists'),
            filePath,
        });
        return exists;
    }
    /**
     * The `getFile()` method returns runtime information about a file path, such as local url, last modified date or size.
     *
     * :::warning
     * Return statement is a dynamic object! It has to be always generated and retrieved by this JS API, as the values in localUri differ platform by platform. Never generate the object manually. `{"localUri":"file://internal/path/to/file.txt"}` is for demonstration only.
     * :::
     *
     * @param filePath The path to the file to be retrieved.
     * @returns {Promise<IFile | null>} A promise that resolves to the file information or `null` if the file does not exist.
     * @throws Error If the `filePath` is not a valid object or does not contain `storageUnit` and `filePath`.
     * @throws Error If the file is a directory.
     * @throws Error If any error occurs during the retrieval operation on the device.
     * @since 2.1.0
     *
     * @example
     * // Get file information
     * const filePath = {
     * 	storageUnit: internalStorageUnit,
     * 	filePath: 'path/to/file.txt',
     * };
     *
     * const fileInfo = await sos.fileSystem.getFile(filePath);
     * console.log(JSON.stringify(fileInfo)); // Prints the file information
     * console.log(fileInfo.localUri); // Prints the local URI of the file
     */
    async getFile(filePath) {
        (0, Validate_1.default)({ filePath }).required().object(types_1.VIFilePath);
        const { file } = await this.postMessage({
            type: this.getMessage('get_file'),
            filePath,
        });
        if (!file) {
            return null;
        }
        return {
            ...file,
            ...filePath,
        };
    }
    /**
     * The `writeFile()` method writes string content to the file specified by `filePath`. If the file does exist, it is created.
     *
     * @param filePath The path to the file to be written.
     * @param contents The content to be written to the file.
     * @returns {Promise<void>} A promise that resolves when the content is written successfully.
     * @throws Error If the parent directory does not exist or the `filePath` is a directory.
     * @throws Error If the `filePath` is not a valid object or does not contain `storageUnit` and `filePath`.
     * @throws Error If any error occurs during the write operation on the device.
     * @since 3.2.0
     *
     * @example
     * const filePath = {
     * 	storageUnit: internalStorageUnit,
     * 	filePath: 'path/to/file.txt',
     * };
     *
     * const contents = 'This is the content to write to the file.';
     * await sos.fileSystem.writeFile(filePath, contents);
     */
    async writeFile(filePath, contents) {
        (0, Validate_1.default)({ filePath }).required().object(types_1.VIFilePath);
        await this.postMessage({
            type: this.getMessage('write_file'),
            filePath,
            contents,
        });
    }
    /**
     * The `appendFile()` method appends string content to the file specified by `filePath`.
     * If the file does exist, it is created.
     *
     * :::note
     * Only string can be appended to the file. If you want to append binary data, you have to convert it to a string first.
     * :::
     *
     * @param filePath The path to the file to be appended.
     * @param contents The content to be appended to the file.
     * @returns {Promise<void>} A promise that resolves when the content is appended successfully.
     * @throws Error If the parent directory does not exist.
     * @throws Error If the `filePath` is a directory.
     * @throws Error If the `filePath` is not a valid object or does not contain `storageUnit` and `filePath`.
     * @throws Error If any error occurs during the append operation on the device.
     * @since
     *
     * @example
     * const filePath = {
     * 	storageUnit: internalStorageUnit,
     * 	filePath: 'path/to/file.txt',
     * };
     *
     * const contents = 'This is the content to append to the file.';
     * await sos.fileSystem.appendFile(filePath, contents);
     */
    async appendFile(filePath, contents) {
        (0, Validate_1.default)({ filePath }).required().object(types_1.VIFilePath);
        await this.postMessage({
            type: this.getMessage('append_file'),
            filePath,
            contents,
        });
    }
    /**
     * The `readFile()` method returns content of the file specified by `filePath`.
     * The file has to be a text file, otherwise the content will be mangled.
     *
     * @param filePath The path to the file to be read.
     * @returns {Promise<string>} A promise that resolves to the content of the file.
     * @throws Error If the file does not exist.
     * @throws Error If the `filePath` is not a valid object or does not contain `storageUnit` and `filePath`.
     * @throws Error If the file is a directory.
     * @throws Error If any error occurs during the read operation on the device.
     * @since 3.3.0
     *
     * @example
     * const filePath = {
     * 	storageUnit: internalStorageUnit,
     * 	filePath: 'path/to/file.txt',
     * };
     *
     * const fileContent = await sos.fileSystem.readFile(filePath);
     * console.log(`Content of the file: ${fileContent}`);
     */
    async readFile(filePath) {
        (0, Validate_1.default)({ filePath }).required().object(types_1.VIFilePath);
        const { contents } = await this.postMessage({
            type: this.getMessage('read_file'),
            filePath,
        });
        return contents;
    }
    /**
     * The `copyFile()` method creates a copy of file from `sourceFilePath` to `destinationFilePath`.
     *
     * @param sourceFilePath The path to the file to be copied.
     * @param destinationFilePath The path where the file will be copied to.
     * @param options Options for copying the file.
     * @param options.overwrite If set to `true`, the method will overwrite the destination file if it already exists.
     * @returns {Promise<void>} A promise that resolves when the file is copied successfully.
     * @throws Error If the source file does not exist.
     * @throws Error If parent of the destination file path does not exist.
     * @throws Error If `options` object is not valid.
     * @throws Error If any error occurs during the copy operation on the device.
     * @since 2.1.0
     *
     * @example
     * // Copy file from one directory to another and overwrite it if it already exists
     * const sourceFilePath = {
     * 	storageUnit: internalStorageUnit,
     * 	filePath: 'path/to/source/file.txt',
     * };
     *
     * const destinationFilePath = {
     * 	storageUnit: internalStorageUnit,
     * 	filePath: 'path/to/destination/file.txt',
     * };
     *
     * await sos.fileSystem.copyFile(sourceFilePath, destinationFilePath, { overwrite: true });
     */
    async copyFile(sourceFilePath, destinationFilePath, options = {}) {
        (0, Validate_1.default)({ sourceFilePath }).required().object(types_1.VIFilePath);
        (0, Validate_1.default)({ destinationFilePath }).required().object(types_1.VIFilePath);
        (0, Validate_1.default)({ options }).required().object(types_1.VICopyFileOptions);
        await this.postMessage({
            type: this.getMessage('copy_file'),
            sourceFilePath,
            destinationFilePath,
            options,
        });
    }
    /**
     * The `moveFile()` method moves a file from `sourceFilePath` to `destinationFilePath`.
     *
     * @param sourceFilePath The path to the file to be moved.
     * @param destinationFilePath The path where the file will be moved to.
     * @param options Options for moving the file.
     * @param options.overwrite If set to `true`, the method will overwrite the destination file if it already exists.
     * @returns {Promise<void>} A promise that resolves when the file is moved successfully.
     * @throws Error If the source file does not exist or parent of the destination file path does not exist.
     * @throws Error If the `options.overwrite` is not set and the destination file path already exists.
     * @throws Error If deleting path does not exist.
     * @throws Error If any error occurs during the move operation on the device.
     * @since 2.1.0
     *
     * @example
     * // Move file from one directory to another and overwrite it if it already exists
     * const sourceFilePath = {
     * 	storageUnit: internalStorageUnit,
     * 	filePath: 'path/to/source/file.txt',
     * };
     *
     * const destinationFilePath = {
     * 	storageUnit: internalStorageUnit,
     * 	filePath: 'path/to/destination/file.txt',
     * };
     *
     * await sos.fileSystem.moveFile(sourceFilePath, destinationFilePath, { overwrite: true });
     */
    async moveFile(sourceFilePath, destinationFilePath, options = {}) {
        (0, Validate_1.default)({ sourceFilePath }).required().object(types_1.VIFilePath);
        (0, Validate_1.default)({ destinationFilePath }).required().object(types_1.VIFilePath);
        (0, Validate_1.default)({ options }).required().object(types_1.VIMoveFileOptions);
        await this.postMessage({
            type: this.getMessage('move_file'),
            sourceFilePath,
            destinationFilePath,
            options,
        });
    }
    /**
     * The `deleteFile()` method deletes the file specified by `filePath`.
     *
     * @param filePath The path to the file or directory to be deleted.
     * @param recursive If set to `true`, the method will delete the directory and all its contents recursively.
     * @returns {Promise<void>} A promise that resolves when the file is deleted successfully.
     * @throws Error If `filePath` is not a valid object or does not contain `storageUnit` and `filePath`.
     * @throws Error If the file does not exist or if `recursive` is set to false and the file path is a directory.
     * @throws Error If deleting path does not exist.
     * @throws Error When is deleting directory and is not empty (not recursive).
     * @since 2.1.0
     *
     * @example
     * // Delete directory and all files inside
     * //// First check, if there is such a directory
     * if (await sos.fileSystem.exists({ storageUnit: internalStorageUnit, filePath: 'test-dir' })) {
     *     // Delete the directory and all it's content recursively
     *     await sos.fileSystem.deleteFile({ storageUnit: internalStorageUnit, filePath: 'test-dir' }, true);
     * }
     *
     * // Delete file
     * //// First check, if there is such a file
     * if (await sos.fileSystem.exists({ storageUnit: internalStorageUnit, filePath: 'test-dir/downloaded-file.png' })) {
     *     // Delete the file
     *     await sos.fileSystem.deleteFile({ storageUnit: internalStorageUnit, filePath: 'test-dir/downloaded-file.png' }, false);
     * }
     */
    async deleteFile(filePath, recursive) {
        (0, Validate_1.default)({ filePath }).required().object(types_1.VIFilePath);
        (0, Validate_1.default)({ recursive }).required().boolean();
        await this.postMessage({
            type: this.getMessage('delete_file'),
            filePath,
            recursive,
        });
    }
    /**
     * The `downloadFile()` method download a file from `sourceUri` and saves it to the specified path. If the file already exists, the file will be
     * overwritten. Optionally, headers for the download request may be specified.
     *
     * :::danger
     * For every download request, our Core Apps makes HEAD request for `content-length` header on that downloaded file. It's due to determining if device has enough space to download the file.
     * :::
     *
     * #### Encoding
     * All downloads respect a standard of `Encoding` with optional compression of files. See [Mozilla standard Accept Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) and [Content Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding).
     *
     * Download file method is always sending optional following headers:
     * ```
     * Accept-Encoding: gzip
     * Accept-Encoding: compress
     * Accept-Encoding: deflate
     * Accept-Encoding: br
     * Accept-Encoding: identity
     * Accept-Encoding: *
     * ```
     *
     * If the server understands the `Encoding` standard, it compresses files using `gzip` algorithm before the files are sent to the client. If so, the response will contain the following headers:
     * ```
     * Content-Encoding: gzip
     * Content-Encoding: compress
     * Content-Encoding: deflate
     * Content-Encoding: br
     * ```
     * So the data communication is compressed under the hood. The client will automatically decompress data before it's saved to a specified location path. So from JS API point of view, there is no requirement to decompress data by itself.
     *
     * The standard is supported on all following platforms:
     *
     * - WebOS 3+
     * - Tizen 2.4+
     * - Brightsign
     * - Raspberry Pi
     * - Windows
     *
     * @param filePath The path where the downloaded file will be saved.
     * @param sourceUri The URI of the file to be downloaded.
     * @param headers Key, value pairs of HTTP headers to send along with the request. Used when the target file is protected by a password or if any
     * @returns {Promise<void>} A promise that resolves when the file is downloaded successfully.
     * @throws Error If `filePath` is not a valid object or does not contain `storageUnit` and `filePath`.
     * @throws Error If `sourceUri` is not a valid URI.
     * @throws Error If `headers` is not a valid object.
     * @throws Error If the parent directory of `filePath` does not exist.
     * @throws Error If the network request fails.
     * @since 2.1.0
     *
     * @example
     * const filePath = {
     * 	storageUnit: internalStorageUnit,
     * 	filePath: 'path/to/downloaded/file.zip',
     * };
     * const sourceUri = 'https://example.com/path/to/file.zip';
     * const headers = {
     * 	'Authorization': 'Bearer your_token_here',
     * };
     * await sos.fileSystem.downloadFile(filePath, sourceUri, headers);
     */
    async downloadFile(filePath, sourceUri, headers) {
        (0, Validate_1.default)({ filePath }).required().object(types_1.VIFilePath);
        (0, Validate_1.default)({ sourceUri }).required().uri();
        (0, Validate_1.default)({ headers }).object();
        await this.postMessage({
            type: this.getMessage('download_file'),
            filePath,
            sourceUri,
            headers,
        });
    }
    /**
     * The `extractFile()` method extract (recursively) the archive file at `archiveFilePath` into a new file specified by `destinationDirectoryPath`.
     *
     * :::note
     * - The directory/folder you are extracting your ZIP file into has to be created BEFORE you start extracting the ZIP.
     * - Only supported extract method is `zip`.
     * :::
     *
     * @param archiveFilePath The path to the archive file to be decompressed.
     * @param destinationDirectoryPath The path to the directory where the decompressed files will be saved.
     * @param method Extract method to use for extracting, e.g. 'zip'.
     * @throws Error If the archive file path does not exist.
     * @throws Error If it is not a valid archive file.
     * @throws Error If destination directory does not exist.
     * @since 2.1.0
     *
     * @example
     * const archiveFilePath = {
     * 	storageUnit: internalStorageUnit,
     * 	filePath: 'path/to/archive.zip',
     * };
     *
     * const destinationDirectoryPath = {
     * 	storageUnit: internalStorageUnit,
     * 	filePath: 'path/to/destination/directory',
     * };
     *
     * await sos.fileSystem.extractFile(archiveFilePath, destinationDirectoryPath, 'zip');
     */
    async extractFile(archiveFilePath, destinationDirectoryPath, method) {
        (0, Validate_1.default)({ archiveFilePath }).required().object(types_1.VIFilePath);
        (0, Validate_1.default)({ destinationDirectoryPath }).object(types_1.VIFilePath);
        (0, Validate_1.default)({ method }).required().string();
        await this.postMessage({
            type: this.getMessage('extract_file'),
            archiveFilePath,
            destinationDirectoryPath,
            method,
        });
    }
    /**
     * The `createArchive()` method creates an archive file from selected files and directories.
     *
     * :::warning
     * - Never start OR end the `filePath` with a slash - `/`.
     * - It is a good practice to check if file exists - `exists()` prior creating it
     * :::
     *
     * :::info
     * - This function is available only on Tizen devices.
     * - All files are added to the archive based on absolute path from root directory.
     * :::
     *
     * @param archiveFilePath The path where the archive file will be created.
     * @param archiveEntries An array of file paths to be included in the archive.
     * @returns {Promise<void>} A promise that resolves when the archive file is created successfully.
     * @throws Error If `archiveFilePath` is not a valid object or does not contain `storageUnit` and `filePath`.
     * @throws Error If `archiveEntries` is not a valid array of objects.
     * @throws Error If the parent directory of `archiveFilePath` does not exist.
     * @throws Error If any of the `archiveEntries` do not exist or are directories.
     * @throws Error If creating the archive file fails.
     * @throws Error If the platform does not support creating archive files.
     * @since 5.12.0
     *
     * @example
     * const archiveFilePath = {
     * 	storageUnit: internalStorageUnit,
     * 	filePath: 'path/to/archive.zip',
     * };
     *
     * const archiveEntries = [
     * 	{
     * 		storageUnit: internalStorageUnit,
     * 		filePath: 'path/to/file1.txt',
     * 	},
     * 	{
     * 		storageUnit: internalStorageUnit,
     * 		filePath: 'path/to/file2.txt',
     * 	},
     * 	{
     * 		storageUnit: internalStorageUnit,
     * 		filePath: 'path/to/directory1',
     * 	},
     * ];
     *
     * await sos.fileSystem.createArchive(archiveFilePath, archiveEntries);
     */
    async createArchive(archiveFilePath, archiveEntries) {
        (0, Validate_1.default)({ archiveFilePath }).required().object(types_1.VIFilePath);
        (0, Validate_1.default)({ archiveEntries }).required().array('object');
        await this.postMessage({
            type: this.getMessage('create_archive_file'),
            archiveFilePath,
            archiveEntries,
        });
    }
    /**
     * The `getChecksumFile()` method computes a checksum of the file specified by `filePath`.
     *
     * :::warning Tizen limitation
     * If you are about to use the MD5 file validation it will automatically return on any Samsung Tizen - 2.4, 3.0 and 4.0.
     * Reason: MD5 file checksum is not available on any Tizen displays due to the Samsung restriction.
     * :::
     *
     * @param filePath The path to the file for which the checksum will be computed.
     * @param hashType The type of hash algorithm to use for computing the checksum.
     * @returns {Promise<string>} A promise that resolves to the computed checksum of the file.
     * @throws Error If `filePath` is not a valid object or does not contain `storageUnit` and `filePath`.
     * @throws Error If `hashType` is not a valid type or string.
     * @throws Error If the file does not exist.
     * @throws Error If `filepath` it is a directory
     *
     * @example
     * const filePath = {
     * 	storageUnit: internalStorageUnit,
     * 	filePath: 'path/to/file.txt',
     * };
     *
     * const checksum = await sos.fileSystem.getFileChecksum(filePath, 'md5');
     * console.log(`Checksum of the file: ${checksum}`);
     */
    async getFileChecksum(filePath, hashType) {
        (0, Validate_1.default)({ filePath }).required().object(types_1.VIFilePath);
        (0, Validate_1.default)({ hashType }).required().string();
        const { checksum } = await this.postMessage({
            type: this.getMessage('get_file_checksum'),
            filePath,
            hashType,
        });
        return checksum;
    }
    /**
     * The `createDirectory()` method create a new directory at specified path.
     *
     * :::warning
     * - Never start OR end the filePath with a slash - `/`.
     * - It is a good practice to check if directory exists - `isDirectory()` prior creating it.
     * :::
     *
     * @param directoryPath The path where the new directory will be created.
     * @returns {Promise<void>} A promise that resolves when the directory is created successfully.
     * @throws Error If `directoryPath` is not a valid object or does not contain `storageUnit` and `filePath`.
     * @throws Error If the directory already exists.
     * @throws Error If parent directory does not exist.
     * @since 2.1.0
     *
     * @example
     * const internalStorageUnit = (await sos.fileSystem.listInternalStorageUnits())[0];
     * const directoryPath = {
     * 	storageUnit: internalStorageUnit,
     * 	filePath: 'path/to/new/directory',
     * };
     *
     * await sos.fileSystem.createDirectory(directoryPath);
     */
    async createDirectory(directoryPath) {
        (0, Validate_1.default)({ directoryPath }).required().object(types_1.VIFilePath);
        await this.postMessage({
            type: this.getMessage('create_directory'),
            directoryPath,
        });
    }
    /**
     * The `isDirectory()` method checks whether the file path points to a directory.
     *
     * @param filePath The file path to check.
     * @returns {Promise<boolean>} A promise that resolves to `true` if the file path is a directory, `false` otherwise.
     * @throws Error If `filePath` is not a valid object or does not contain `storageUnit` and `filePath`.
     * @throws Error If the file path does not exist.
     * @since 2.1.0
     *
     * @example
     * const filePath = {
     * 	storageUnit: internalStorageUnit,
     * 	filePath: 'path/to/directory',
     * };
     * const isDir = await sos.fileSystem.isDirectory(filePath);
     * if (isDir) {
     * 	console.log('The file path is a directory.');
     * } else {
     * 	console.log('The file path is not a directory.');
     * }
     */
    async isDirectory(filePath) {
        (0, Validate_1.default)({ filePath }).required().object(types_1.VIFilePath);
        const { isDirectory } = await this.postMessage({
            type: this.getMessage('is_directory'),
            filePath,
        });
        return isDirectory;
    }
    /**
     * The `link()` method creates a symbolic link from `sourceFilePath` (existing path) to `destinationFilePath` (new path).
     *
     * :::note
     * This method is only available on Linux devices.
     * :::
     *
     * @param sourceFilePath The path to the existing file or directory that you want to link to.
     * @param destinationFilePath The path where the symbolic link will be created.
     * @throws Error If `sourceFilePath` or `destinationPath` is not a valid object or does not contain `storageUnit` and `filePath`.
     * @throws Error If the `sourceFilePath` does not exist or if the `destinationFilePath` already exists.
     * @throws Error The platform does not support linking directories.
     * @returns {Promise<void>} A promise that resolves when the symbolic link is created successfully.
     * @since 4.0.0
     *
     * @example
     * const internalStorageUnit = (await sos.fileSystem.listInternalStorageUnits())[0];
     * const sourceFilePath = {
     * 	storageUnit: internalStorageUnit,
     * 	filePath: 'path/to/existing/file.txt',
     * };
     *
     * const destinationFilePath = {
     * 	storageUnit: internalStorageUnit,
     * 	filePath: 'path/to/symlink/file_link.txt',
     * };
     *
     * await sos.fileSystem.link(sourceFilePath, destinationFilePath);
     */
    async link(sourceFilePath, destinationFilePath) {
        (0, Validate_1.default)({ sourceFilePath }).required().object(types_1.VIFilePath);
        (0, Validate_1.default)({ destinationFilePath }).required().object(types_1.VIFilePath);
        await this.postMessage({
            type: this.getMessage('link'),
            sourceFilePath,
            destinationFilePath,
        });
    }
    /**
     * The `wipeout()` method is used to wipe out all data from the file system.
     *
     * :::danger
     * - Ensure that function is called only once, otherwise it will wipe out the file system again on applet or device start!
     * - This function is clearing internal file system storage, cache storage and cookies. Local storage will not be cleared.
     * :::
     *
     * @returns {Promise<void>} A promise that resolves when the wipeout is complete.
     *
     * @example
     * await sos.fileSystem.wipeout().then(() => {
     * 	console.log('File system wiped out successfully.');
     * 	await sos.management.power.systemReboot(); // Reboot the device after wipeout
     * }).catch((error) => {
     * 	console.error('Error wiping out file system:', error);
     * });
     */
    async wipeout() {
        await this.postMessage({
            type: this.getMessage('wipeout'),
        });
    }
    /** @internal */
    handleMessageData(data) {
        switch (data.type) {
            case this.getMessage('storage_units_changed'):
                this.eventEmitter.emit(EVENT_STORAGE_UNITS_CHANGED);
                break;
            default:
        }
    }
    getMessage(name) {
        return this.messagePrefix + '.' + FileSystem.MESSAGE_PREFIX + '.' + name;
    }
}
exports.default = FileSystem;
//# sourceMappingURL=FileSystem.js.map