/* UtilLib - Copyright (c) 2022-2025 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package net.mapeadores.util.io;

import java.util.List;
import java.util.RandomAccess;
import java.util.SortedMap;
import java.util.TreeMap;
import net.mapeadores.util.annotation.Nullable;
import net.mapeadores.util.mimetype.MimeTypeResolver;
import net.mapeadores.util.mimetype.MimeTypeUtils;
import net.mapeadores.util.text.RelativePath;


/**
 *
 * @author Vincent Calame
 */
public interface ResourceStorages extends List<ResourceStorage>, RandomAccess {

    @Nullable
    public ResourceStorage getResourceStorage(String name);


    public default boolean containsResource(RelativePath path) {
        for (ResourceStorage resourceStorage : this) {
            boolean here = resourceStorage.containsResource(path);
            if (here) {
                return true;
            }
        }
        return false;
    }

    @Nullable
    public default DocStream getResourceDocStream(RelativePath path, MimeTypeResolver mimeTypeResolver) {
        String fileName = path.getLastName();
        if (fileName.startsWith("_")) {
            int idx = fileName.indexOf('_', 1);
            if (idx != -1) {
                String storageName = fileName.substring(1, idx);
                ResourceStorage resourceStorage = getResourceStorage(storageName);
                if (resourceStorage != null) {
                    path = RelativePath.build(path.getParentPath() + fileName.substring(idx + 1));
                    return resourceStorage.getResourceDocStream(path, mimeTypeResolver);
                }
            }
        }
        for (ResourceStorage resourceStorage : this) {
            DocStream docStream = resourceStorage.getResourceDocStream(path, mimeTypeResolver);
            if (docStream != null) {
                return docStream;
            }
        }
        return null;
    }

    @Nullable
    public default DocStream getResourceDocStream(RelativePath path) {
        return getResourceDocStream(path, MimeTypeUtils.DEFAULT_RESOLVER);
    }

    public default SortedMap<String, RelativePath> listResources(RelativePath relativePath, boolean recursive) {
        TreeMap<String, RelativePath> map = new TreeMap<String, RelativePath>();
        for (ResourceStorage resourceStorage : this) {
            ResourceFolder folder = resourceStorage.getResourceFolder(relativePath);
            if (folder != null) {
                for (String resourceName : folder.getResourceNameList()) {
                    map.put(resourceName, relativePath.buildChild(resourceName));
                }
                if (recursive) {
                    for (ResourceFolder subfolder : folder.getSubfolderList()) {
                        String folderName = subfolder.getName();
                        ResourceUtils.addSubressources(map, subfolder, relativePath.buildChild(folderName), folderName + "/");
                    }
                }
            }
        }
        return map;
    }

    public default SortedMap<String, RelativePath> listSubFolders(RelativePath relativePath) {
        TreeMap<String, RelativePath> map = new TreeMap<String, RelativePath>();
        for (ResourceStorage resourceStorage : this) {
            ResourceFolder folder = resourceStorage.getResourceFolder(relativePath);
            if (folder != null) {
                for (ResourceFolder subfolder : folder.getSubfolderList()) {
                    String name = subfolder.getName();
                    if (!map.containsKey(name)) {
                        map.put(name, relativePath.buildChild(name));
                    }
                }
            }
        }
        return map;
    }


}
