package lc.esp.script.engine;

import lc.mecha.log.MechaLogger;
import lc.mecha.log.MechaLoggerFactory;
import org.graalvm.polyglot.io.FileSystem;

import java.io.IOException;
import java.net.URI;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.*;
import java.nio.file.attribute.FileAttribute;
import java.util.Map;
import java.util.Set;

/**
 * This implementation of {@link FileSystem} is backed by EOFS and allows executing scripts to load modules from
 * EOFS. The major impedence here is that the script environments expects a random access file, but the grid
 * filesystem does not work this way. Consequently, files have to be downloaded in their entirety first before
 * a seekable channel can be created.
 *
 * The filesystem implementation is required to provide a seekable byte channel representing the underlying file.
 * Since EOFS is not really random access, this implementation will transfer the entire contents of the file
 * and then provide a seekable channel to that local copy.
 *
 * @author Alex Leigh
 * @since mk20 (TOKYO PROTOCOL)
 */
public class EOFileSystem implements FileSystem {
    private static final MechaLogger logger = MechaLoggerFactory.getLogger(EOFileSystem.class);

    @Override
    public Path parsePath(URI uri) {
        logger.info("parsePath [uri: {}]", uri);
        return Paths.get(uri);
    }

    @Override
    public Path parsePath(String path) {
        logger.info("parsePath [path: {}]", path);
        return Paths.get(path);
    }

    @Override
    public void checkAccess(Path path, Set<? extends AccessMode> modes, LinkOption... linkOptions) throws IOException {
        logger.info("checkAccess [path: {}]", path);
    }

    @Override
    public void createDirectory(Path dir, FileAttribute<?>... attrs) throws IOException {
        logger.info("createDirectory [dir: {}]", dir);

    }

    @Override
    public void delete(Path path) throws IOException {
        logger.info("delete {}", path);

    }

    @Override
    public SeekableByteChannel newByteChannel(Path path, Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException {
        logger.info("newByteChannel [path: {}]", path);
        return null;
    }

    @Override
    public DirectoryStream<Path> newDirectoryStream(Path dir, DirectoryStream.Filter<? super Path> filter) throws IOException {
        logger.info("newDirectoryStream [dir: {}]", dir);
        return null;
    }

    @Override
    public Path toAbsolutePath(Path path) {
        logger.info("toAbsolutePath [path: {}]", path);
        return path;
    }

    @Override
    public Path toRealPath(Path path, LinkOption... linkOptions) throws IOException {
        logger.info("toRealPath [path: {}]", path);
        return path;
    }

    @Override
    public Map<String, Object> readAttributes(Path path, String attributes, LinkOption... options) throws IOException {
        logger.info("readAttributes [path: {}]", path);
        return null;
    }
}
