@startuml
scale 2
skinparam shadowing false
skinparam classFontSize 11

' PNG (лимит растра по умолчанию 4096): PLANTUML_LIMIT_SIZE=8192 java -Xmx2g -jar plantuml.jar -charset UTF-8 -tpng …

package usecases {
    class ManageStoragesEncryptionUseCase {
        + enableEncryption(IStorageInfo, EncryptKey, boolean): Unit
        + openStorage(IStorageInfo, EncryptKey, boolean): Unit
        + clearAndDisableEncryption(IStorageInfo): Unit
        + closeStorage(IStorageInfo): Unit
        + canEncrypt(IStorageInfo): Unit
        + changePassword(IStorageInfo, EncryptKey, boolean): Unit
    }
    class RemoveStorageUseCase {
        + remove(IStorageInfo): Unit
    }
    class GetOpenedStoragesUseCase {
        + getOpenedStorages(): StateFlow<Map<UUID, IStorageInfo>>
    }
    class ManageLocalVaultUseCase {
        + getLocalStorages(): StateFlow<List<IStorageInfo>>
        + createStorage(): Unit
    }
    class StorageFileManagementUseCase {
        + getAllDirs(): Unit
        + setStorage(IStorageInfo): void
        + getAllFiles(): Unit
    }
    class RenameStorageUseCase {
        + rename(IStorageInfo, String): Unit
    }
}

package tasks {
    class TaskLogLine {
        + getTimestampMs(): long
        + getLevel(): TaskLogLevel
        + getMessage(): String
    }
    class PipelineWork {
        + run(TaskContext): Unit
    }
    class TaskContext {
        + reportProgress(Float, String): Unit
        + reportProgress(TaskProgress): Unit
        + log(TaskLogLevel, String): void
        + getTaskId(): TaskId
    }
    class PipelineState {
        + getTasks(): List
        + getRunningTaskIds(): Set
    }
    class ITaskOrchestrator {
        + getLogLines(): StateFlow<List<TaskLogLine>>
        + enqueue(String, PipelineWork): TaskId
        + getPipelineState(): StateFlow<PipelineState>
        + getForegroundUi(): StateFlow<TaskForegroundUiState>
        + cancel(TaskId): boolean
        + cancelAll(): void
    }
    class TaskProgress {
        + getLabel(): String
        + getFraction(): Float
    }
    class TaskForegroundUiState {
    }
    class TaskForegroundItem {
        + getProgress(): TaskProgress
        + getTitle(): String
        + getTaskId(): TaskId
    }
    class TaskLogLevel {
        + Debug
        + Warn
        + Error
        + Info
        + values(): TaskLogLevel[]
        + valueOf(String): TaskLogLevel
        + getEntries(): EnumEntries<TaskLogLevel>
    }
    class TaskRunState {
    }
    class TaskId {
        + getUuid(): UUID
    }
    class PipelineTask {
        + getId(): TaskId
        + getDispatcher(): CoroutineDispatcher
        + getState(): TaskRunState
        + getTitle(): String
    }
}

package interfaces {
    class ILogger {
        + debug(String, String): void
    }
    class IYandexVault {
        + getAccountEmail(): String
    }
    class IMetaInfo {
        + getSize(): long
        + isDeleted(): boolean
        + isHidden(): boolean
        + getLastModified(): Instant
        + getPath(): String
    }
    class IStorage {
        + rename(String): Unit
        + setEncInfo(StorageEncryptionInfo): Unit
        + isEmpty(): Flow<Boolean>
        + getUuid(): UUID
        + getAccessor(): IStorageAccessor
        + isAvailable(): StateFlow<Boolean>
        + getSize(): StateFlow<Long>
        + getNumberOfFiles(): StateFlow<Integer>
        + clearAllContent(): Unit
        + getMetaInfo(): StateFlow<IStorageMetaInfo>
        + isVirtualStorage(): boolean
    }
    class IVaultsManager {
        + getLocalVault(): IVault
        + removeRemoteVault(UUID): Unit
        + addYandexVault(String): Unit
        + getRemoteVaults(): StateFlow<List<IVault>>
        + getAllStorages(): StateFlow<List<IStorage>>
        + getAllVaults(): StateFlow<List<IVault>>
        + getUnlockManager(): IUnlockManager
    }
    class IStorageMetaInfo {
        + getEncInfo(): StorageEncryptionInfo
        + getName(): String
        + getLastModified(): Instant
    }
    class IFile {
        + getMetaInfo(): IMetaInfo
    }
    class IStorageInfo {
        + isEmpty(): Flow<Boolean>
        + getUuid(): UUID
        + isAvailable(): StateFlow<Boolean>
        + getSize(): StateFlow<Long>
        + getNumberOfFiles(): StateFlow<Integer>
        + getMetaInfo(): StateFlow<IStorageMetaInfo>
        + isVirtualStorage(): boolean
    }
    class IStorageExplorer {
        + getCurrentPath(): StateFlow<String>
    }
    class IVaultInfo {
        + getAvailableSpace(): StateFlow<Integer>
        + getType(): VaultType
        + getTotalSpace(): StateFlow<Integer>
        + getUuid(): UUID
        + isAvailable(): StateFlow<Boolean>
        + getStorages(): StateFlow<List<IStorageInfo>>
    }
    class IUnlockManager {
        + close(IStorage): Unit
        + close(UUID): Unit
        + open(IStorage, EncryptKey, boolean): Unit
        + getOpenedStorages(): StateFlow<Map<UUID, IStorage>>
    }
    class IDirectory {
        + getMetaInfo(): IMetaInfo
        + getElementsCount(): Integer
    }
    class IStorageAccessor {
        + getFilesFlow(String): Flow<DataPackage<List<IFile>>>
        + getDirs(String): Unit
        + getDirsUpdates(): SharedFlow<DataPackage<List<IDirectory>>>
        + touchDir(String): Unit
        + getFiles(String): Unit
        + getSize(): StateFlow<Long>
        + isAvailable(): StateFlow<Boolean>
        + getDirInfo(String): Unit
        + openRead(String): Unit
        + moveToTrash(String): Unit
        + delete(String): Unit
        + touchFile(String): Unit
        + getAllDirs(): Unit
        + openWrite(String): Unit
        + getAllFiles(): Unit
        + getDirsFlow(String): Flow<DataPackage<List<IDirectory>>>
        + getNumberOfFiles(): StateFlow<Integer>
        + getFilesUpdates(): SharedFlow<DataPackage<List<IFile>>>
        + setHidden(String, boolean): Unit
        + getFileInfo(String): Unit
    }
    class IVault {
        + getAvailableSpace(): StateFlow<Integer>
        + getType(): VaultType
        + getTotalSpace(): StateFlow<Integer>
        + remove(IStorage): Unit
        + createStorage(StorageEncryptionInfo): Unit
        + getUuid(): UUID
        + isAvailable(): StateFlow<Boolean>
        + getStorages(): StateFlow<List<IStorage>>
        + createStorage(): Unit
    }
}

package encrypt {
    class EncryptorWithStaticIv {
        + decryptBytesbyte[](byte[])
        + encryptStream(java.io.OutputStream): java.io.OutputStream
        + decryptStream(java.io.InputStream): java.io.InputStream
        + encryptBytesbyte[](byte[])
        + dispose(): void
        + encryptString(String): String
        + decryptString(String): String
    }
    class Encryptor {
        + AES_SETTINGS: String
        + IV_LEN: int
        + decryptBytesbyte[](byte[])
        + encryptStream(java.io.OutputStream): java.io.OutputStream
        + decryptStream(java.io.InputStream): java.io.InputStream
        + encryptBytesbyte[](byte[])
        + dispose(): void
        + encryptString(String): String
        + decryptString(String): String
    }
}

package datatypes {
    class Tree {
        + getValue(): Unit
        + getChildren(): List
        + setChildren(List): void
    }
    class EncryptKey {
        + toAesKey(): SecretKeySpec
        + getBytes(): byte[]
    }
    class DataPackage {
        + getData(): Unit
        + isError(): Boolean
        + isLoading(): Boolean
    }
    class DataPage {
        + getPageLength(): int
        + getPageIndex(): int
        + getHasNext(): Boolean
    }
    class StorageEncryptionInfo {
        + getEncryptedTestData(): String
        + getPathIv(): byte[]
    }
}

package common.impl {
    class CommonDirectory {
        + getElementsCount(): Integer
        + getMetaInfo(): CommonMetaInfo
    }
    class CommonStorageMetaInfo {
        + getEncInfo(): StorageEncryptionInfo
        + getName(): String
        + getLastModified(): Instant
    }
    class CommonMetaInfo {
        + getSize(): long
        + getPath(): String
        + isDeleted(): boolean
        + isHidden(): boolean
        + getLastModified(): Instant
    }
    class CommonFile {
        + getMetaInfo(): IMetaInfo
    }
}

package auth {
    class RemoteYandexAuthResult {
    }
    class RemoteYandexSignInLauncher {
        + launch(): void
    }
}

package enums {
    class VaultType {
        + DECRYPTED: VaultType
        + LOCAL: VaultType
        + YANDEX: VaultType
        + valueOf(String): VaultType
        + values(): VaultType[]
        + getEntries(): EnumEntries<VaultType>
    }
}

usecases.ManageStoragesEncryptionUseCase ..> interfaces.IStorageMetaInfo
usecases.ManageStoragesEncryptionUseCase ..> interfaces.IStorageInfo
usecases.ManageStoragesEncryptionUseCase ..> tasks.TaskProgress
usecases.ManageStoragesEncryptionUseCase ..> datatypes.EncryptKey
usecases.ManageStoragesEncryptionUseCase ..> encrypt.Encryptor
usecases.ManageStoragesEncryptionUseCase ..> interfaces.IStorage
usecases.ManageStoragesEncryptionUseCase ..> interfaces.IUnlockManager
usecases.ManageStoragesEncryptionUseCase ..> datatypes.StorageEncryptionInfo
usecases.RemoveStorageUseCase ..> usecases.ManageStoragesEncryptionUseCase
usecases.RemoveStorageUseCase ..> interfaces.IStorage
usecases.RemoveStorageUseCase ..> interfaces.IStorageInfo
usecases.RemoveStorageUseCase ..> interfaces.IVaultsManager
usecases.RemoveStorageUseCase ..> interfaces.IUnlockManager
usecases.RemoveStorageUseCase ..> interfaces.IVault
tasks.TaskLogLine ..> tasks.TaskLogLevel
tasks.PipelineWork ..> tasks.TaskContext
interfaces.IVault <|.. interfaces.IYandexVault
interfaces.IVaultInfo <|.. interfaces.IYandexVault
interfaces.IYandexVault ..> interfaces.IStorage
interfaces.IYandexVault ..> interfaces.IVault
interfaces.IYandexVault ..> enums.VaultType
interfaces.IYandexVault ..> datatypes.StorageEncryptionInfo
usecases.GetOpenedStoragesUseCase ..> interfaces.IStorageInfo
usecases.GetOpenedStoragesUseCase ..> interfaces.IUnlockManager
tasks.TaskContext ..> tasks.TaskLogLevel
tasks.TaskContext ..> tasks.TaskProgress
tasks.TaskContext ..> tasks.TaskId
usecases.ManageLocalVaultUseCase ..> interfaces.IStorageInfo
usecases.ManageLocalVaultUseCase ..> interfaces.IVaultsManager
usecases.ManageLocalVaultUseCase ..> interfaces.IVault
usecases.StorageFileManagementUseCase ..> interfaces.IFile
usecases.StorageFileManagementUseCase ..> interfaces.IStorage
usecases.StorageFileManagementUseCase ..> interfaces.IStorageInfo
usecases.StorageFileManagementUseCase ..> interfaces.IDirectory
usecases.StorageFileManagementUseCase ..> interfaces.IStorageAccessor
interfaces.IStorageInfo <|.. interfaces.IStorage
interfaces.IStorage ..> interfaces.IStorageMetaInfo
interfaces.IStorage ..> interfaces.IStorageInfo
interfaces.IStorage ..> tasks.TaskProgress
interfaces.IStorage ..> interfaces.IStorageAccessor
interfaces.IStorage ..> datatypes.StorageEncryptionInfo
interfaces.IVaultsManager ..> interfaces.IStorage
interfaces.IVaultsManager ..> interfaces.IUnlockManager
interfaces.IVaultsManager ..> interfaces.IVault
interfaces.IDirectory <|.. common.impl.CommonDirectory
common.impl.CommonDirectory ..> common.impl.CommonMetaInfo
common.impl.CommonDirectory ..> interfaces.IMetaInfo
common.impl.CommonDirectory ..> interfaces.IDirectory
tasks.PipelineState ..> tasks.TaskId
tasks.PipelineState ..> tasks.PipelineTask
interfaces.IStorageMetaInfo <|.. common.impl.CommonStorageMetaInfo
common.impl.CommonStorageMetaInfo ..> interfaces.IStorageMetaInfo
common.impl.CommonStorageMetaInfo ..> datatypes.StorageEncryptionInfo
interfaces.IMetaInfo <|.. common.impl.CommonMetaInfo
common.impl.CommonMetaInfo ..> interfaces.IMetaInfo
interfaces.IStorageMetaInfo ..> datatypes.StorageEncryptionInfo
interfaces.IFile ..> interfaces.IMetaInfo
tasks.ITaskOrchestrator ..> tasks.TaskLogLine
tasks.ITaskOrchestrator ..> tasks.PipelineState
tasks.ITaskOrchestrator ..> tasks.TaskForegroundUiState
tasks.ITaskOrchestrator ..> tasks.PipelineWork
tasks.ITaskOrchestrator ..> tasks.TaskId
interfaces.IStorageInfo ..> interfaces.IStorageMetaInfo
interfaces.IStorageInfo ..> interfaces.IStorage
usecases.RenameStorageUseCase ..> interfaces.IStorage
usecases.RenameStorageUseCase ..> interfaces.IStorageInfo
interfaces.IVaultInfo ..> interfaces.IStorageInfo
interfaces.IVaultInfo ..> interfaces.IVault
interfaces.IVaultInfo ..> enums.VaultType
tasks.TaskForegroundItem ..> tasks.TaskProgress
tasks.TaskForegroundItem ..> tasks.TaskId
interfaces.IUnlockManager ..> interfaces.IStorage
interfaces.IUnlockManager ..> datatypes.EncryptKey
interfaces.IDirectory ..> interfaces.IMetaInfo
interfaces.IStorageAccessor ..> interfaces.IFile
interfaces.IStorageAccessor ..> interfaces.IDirectory
interfaces.IStorageAccessor ..> datatypes.DataPackage
interfaces.IVaultInfo <|.. interfaces.IVault
interfaces.IVault ..> interfaces.IStorage
interfaces.IVault ..> interfaces.IVaultInfo
interfaces.IVault ..> enums.VaultType
interfaces.IVault ..> datatypes.StorageEncryptionInfo
auth.RemoteYandexSignInLauncher ..> auth.RemoteYandexAuthResult
datatypes.DataPackage <|-- datatypes.DataPage
datatypes.DataPage ..> datatypes.DataPackage
interfaces.IFile <|.. common.impl.CommonFile
common.impl.CommonFile ..> interfaces.IMetaInfo
common.impl.CommonFile ..> interfaces.IFile
tasks.PipelineTask ..> tasks.TaskRunState
tasks.PipelineTask ..> tasks.TaskId

@enduml
