<?php

namespace OCA\GroupfolderFilesystemSnapshots\Manager;

use OCP\IConfig;
use OCP\Files\IRootFolder;

use OCA\GroupFolders\Folder\FolderManager;
use OCA\GroupFolders\Mount\MountProvider;

use OCA\GroupfolderFilesystemSnapshots\Service\SettingsService;

class PathManager {

	public function __construct(
			private IConfig $config,
			private IRootFolder $rootFolder,
			private FolderManager $groupfolderFolderManager,
			private MountProvider $mountProvider,
			private SettingsService $settingsService,
		){}

	public function getFilesystemMountpointPath() {
		return $this->settingsService->getAppValue("filesystem_mountpoint_path");
	}

	public function getFilesystemSnapshotsPath() {
		return $this->settingsService->getAppValue("filesystem_snapshots_path");
	}

	// Nextcloud general
	public function getDataDirectory() {
		return $this->config->getSystemValue("datadirectory");
	}

	private function getRootFolderStorageId(): ?int {
		return $this->rootFolder->getMountPoint()->getNumericStorageId();
	}

	// Snapshots
	public function getSnapshotPath(string $snapshotId) {
		return realpath($this->getFilesystemSnapshotsPath() . DIRECTORY_SEPARATOR . $snapshotId . DIRECTORY_SEPARATOR);
	}

	public function convertToSnapshotPath(string $filesystemPath, string $snapshotId) {
		$filesystemMountpointPath = $this->getFilesystemMountpointPath();
		$filesystemPath = realpath($filesystemPath);

		if($filesystemMountpointPath == '') {
			return false;
		}

		if(!str_starts_with($filesystemPath, $filesystemMountpointPath)) {
			return false;
		}

		return str_replace($filesystemMountpointPath, $this->getSnapshotPath($snapshotId) . DIRECTORY_SEPARATOR, $filesystemPath);
	}

	// Groupfolders
	public function getGroupfolderById(int $groupfolderId) {
		$storageId = $this->getRootFolderStorageId();
		if (!is_null($storageId)) {
			return $this->groupfolderFolderManager->getFolder($groupfolderId, $storageId);
		}
	}
	public function getGroupfolderMountById(int $groupfolderId) {
		return $this->mountProvider->getFolder($groupfolderId, False);
	}
	private function checkIfGroupfolderExists(int $groupfolderId): bool {
		$storageId = $this->getRootFolderStorageId();
		if ($storageId === null) {
			return "storage Id null";
		}

		$folder = $this->groupfolderFolderManager->getFolder($groupfolderId, $storageId);
		if ($folder === false) {
			return "Folder does not exist";
		}
		
		return true;
	}

	public function getGroupFolderDirectory(int $groupfolderId, string $relativePath) {
		$groupFolder = $this->getGroupfolderMountById($groupfolderId);
		$relativeToDataDirectoryPath = $groupFolder->get($relativePath)->getInternalPath();
		$minPath = realpath($this->getDataDirectory() . DIRECTORY_SEPARATOR . $groupFolder->getInternalPath() . DIRECTORY_SEPARATOR);
		$realPath = realpath($this->getDataDirectory() . DIRECTORY_SEPARATOR . $relativeToDataDirectoryPath . DIRECTORY_SEPARATOR);

		// Data directory and groupfolder directory have to actually exist
		if(!file_exists($minPath) || !file_exists($realPath)) {
			return false;
		}

		// the group subfolder directory always has to start with the groupfolder directory
		// prevents usage of ".." in relativePath to escape out of groupfolder or even data directory
		if(!str_starts_with($realPath, $minPath)) {
			return false;
		}

		return $realPath;
	}

	public function getGroupFolderSnapshotDirectory(int $groupfolderId, string $relativePath, string $snapshotId) {
		return $this->convertToSnapshotPath($this->getGroupFolderDirectory($groupfolderId, $relativePath), $snapshotId);
	}
}