package de.nbscloud.files;

import de.nbscloud.files.config.FilesConfig;
import de.nbscloud.files.controller.FilesController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.nio.file.Path;
import java.nio.file.Paths;

@Component
public class LocationTracker {
    private static final Logger logger = LoggerFactory.getLogger(LocationTracker.class);

    @Autowired
    private FilesConfig filesConfig;

    private Path baseDirPath;
    private Path currentLocation;

    public void init() {
        this.baseDirPath = Paths.get(this.filesConfig.getBaseDir());
        this.currentLocation = this.baseDirPath.resolve("");

        logger.info("Initialized location to {}", this.currentLocation);
    }

    public void reset() {
        logger.debug("Reset location");

        init();
    }

    public Path getCurrentLocation() {
        return this.currentLocation;
    }

    public Path getRelativeLocation() {
        return this.baseDirPath.relativize(this.currentLocation);
    }

    public Path getRelativeToBaseDir(Path other) {
        return this.baseDirPath.relativize(other);
    }

    public Path getTrashBin() {
        return this.baseDirPath.resolve(this.filesConfig.getTrashBinName());
    }

    public boolean isTrashBin() {
        return this.currentLocation.equals(this.getTrashBin());
    }

    public boolean isBasePath() {
        return this.baseDirPath.equals(this.currentLocation);
    }

    public Path getParent() {
        return this.baseDirPath.relativize(this.currentLocation.getParent());
    }

    public void setCurrentLocation(String navigateTo) {
        validate(navigateTo);

        this.currentLocation = this.baseDirPath.resolve(navigateTo);
    }

    private void validate(String navigateTo) {
        if(navigateTo == null) {
            throw new IllegalStateException("Null");
        }

        if(navigateTo.contains("..")) {
            throw new IllegalStateException("Relative path");
        }

        if (Paths.get(navigateTo).isAbsolute()) {
            throw new IllegalStateException("Absolute path: " + navigateTo);
        }

        if(!this.baseDirPath.resolve(navigateTo).startsWith(this.baseDirPath)) {
            throw new IllegalStateException("Illegal path: " + navigateTo);
        }
    }

    public Path getBaseDirPath() {
        return baseDirPath;
    }
}
