# Copyright (C) 2007-2023 Andrea Francia Trivolzio(PV) Italy
from typing import List

from trashcli.fstab.volume_of import VolumeOf
from trashcli.lib.environ import Environ
from trashcli.lib.trash_dirs import (
    volume_trash_dir1, volume_trash_dir2, home_trash_dir)
from trashcli.put.core.candidate import Candidate
from trashcli.put.core.check_type import NoCheck, TopTrashDirCheck
from trashcli.put.core.path_maker_type import PathMakerType
from trashcli.put.gate import Gate


class TrashDirectoriesFinder:
    def __init__(self,
                 fs,  # type: VolumeOf
                 ):
        self.fs = fs

    def possible_trash_directories_for(self,
                                       volume,  # type: str
                                       specific_trash_dir,  # type: str
                                       environ,  # type: Environ
                                       uid,  # type: int
                                       home_fallback,  # type: bool
                                       ):  # type: (...) -> List[Candidate]
        trash_dirs = []

        def add_home_trash(path, volume, gate):
            trash_dirs.append(
                Candidate(trash_dir_path=path,
                          volume=volume,
                          path_maker_type=PathMakerType.AbsolutePaths,
                          check_type=NoCheck,
                          gate=gate))

        def add_top_trash_dir(path, volume):
            trash_dirs.append(
                Candidate(trash_dir_path=path,
                          volume=volume,
                          path_maker_type=PathMakerType.RelativePaths,
                          check_type=TopTrashDirCheck,
                          gate=Gate.SameVolume))

        def add_alt_top_trash_dir(path, volume):
            trash_dirs.append(
                Candidate(trash_dir_path=path,
                          volume=volume,
                          path_maker_type=PathMakerType.RelativePaths,
                          check_type=NoCheck,
                          gate=Gate.SameVolume))

        if specific_trash_dir:
            path = specific_trash_dir
            volume = self.fs.volume_of(path)
            trash_dirs.append(
                Candidate(trash_dir_path=path,
                          volume=volume,
                          path_maker_type=PathMakerType.RelativePaths,
                          check_type=NoCheck,
                          gate=Gate.SameVolume))
        else:
            for path, dir_volume in home_trash_dir(environ, self.fs):
                add_home_trash(path, dir_volume, Gate.SameVolume)
            for path, dir_volume in volume_trash_dir1(volume, uid):
                add_top_trash_dir(path, dir_volume)
            for path, dir_volume in volume_trash_dir2(volume, uid):
                add_alt_top_trash_dir(path, dir_volume)
            if home_fallback:
                for path, dir_volume in home_trash_dir(environ, self.fs):
                    add_home_trash(path, dir_volume, Gate.HomeFallback)
        return trash_dirs
