package nl.hsac.fitnesse.fixture.slim;

import nl.hsac.fitnesse.fixture.util.FileUtil;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * Utility fixture to work with files.
 */
public class FileFixture extends SlimFixtureWithMap {
    private String directory = new File(filesDir, "fileFixture").getPath() + File.separator;

    public void setDirectory(String aDirectory) {
        if (isFilesUrl(aDirectory)) {
            String url = getUrl(aDirectory);
            String relativeDir = url.substring("files".length());
            relativeDir = relativeDir.replace('/', File.separatorChar);
            directory = filesDir + relativeDir;
        } else {
            directory = aDirectory;
        }
        if (!directory.endsWith(File.separator)) {
            directory += File.separator;
        }
    }

    public String createContaining(String filename, String content) {
        String fullName = getFullName(filename);
        ensureParentExists(fullName);
        File f = FileUtil.writeFile(fullName, content);
        return linkToFile(f);
    }

    public String textIn(String filename) throws IOException {
        String text = "";
        String fullName = getFullName(filename);
        if (sizeOf(filename) > 0) {
            try {
                FileInputStream s = new FileInputStream(fullName);
                text = FileUtil.streamToString(s, fullName);
            } catch (FileNotFoundException e) {
                throw new SlimFixtureException(false, "Unable to find: " + fullName);
            }
        }
        return text;
    }

    public String contentOf(String filename) throws IOException {
        String content = textIn(filename);
        return getEnvironment().getHtml(content);
    }

    public String createUsing(String filename, String templateName) {
        String content = getEnvironment().processTemplate(templateName, getCurrentValues());
        return createContaining(filename, content);
    }

    public String copyTo(String sourceName, String targetName) throws IOException {
        String fullSource = getFullName(sourceName);
        // ensure file exists
        getFile(fullSource);

        String fullTarget = getFullName(targetName);
        ensureParentExists(fullTarget);
        File destFile = FileUtil.copyFile(fullSource, fullTarget);
        return linkToFile(destFile);
    }

    public long sizeOf(String filename) {
        String fullName = getFullName(filename);
        File file = getFile(fullName);
        return file.length();
    }

    protected File getFile(String fullName) {
        File file = new File(fullName);
        if (!file.exists()) {
            throw new SlimFixtureException(false, "Unable to find: " + file.getAbsolutePath());
        }
        return file;
    }

    protected void ensureParentExists(String fullName) {
        File f = new File(fullName);
        File parentFile = f.getParentFile();
        parentFile.mkdirs();
    }

    protected String getFullName(String filename) {
        String name;
        if (filename.startsWith(File.separator)
                || ":\\".equals(filename.substring(1, 3))) {
            name = filename;
        } else if (isFilesUrl(filename)){
            name = getFilePathFromWikiUrl(filename);
        } else {
            name = directory + filename;
        }
        return cleanupPath(name);
    }

    private boolean isFilesUrl(String filename) {
        String url = getUrl(filename);
        return !filename.equals(url) && url.startsWith("files/");
    }

    private String cleanupPath(String fullPath) {
        String clean;
        if ("\\".equals(File.separator)) {
            clean = fullPath.replaceAll("/", "\\\\");
        } else {
            clean = fullPath.replaceAll("\\\\", File.separator);
        }
        return clean;
    }

    protected String linkToFile(File f) {
        String url = getWikiUrl(f.getAbsolutePath());
        if (url == null) {
            url = f.toURI().toString();
        }
        return String.format("<a href=\"%s\">%s</a>", url, f.getName());
    }

}

@@ -3756,23 +3756,28 @@
 lace
-All
 (%22/%22, 
-%22%5C%5C%5C%5C%22
+File.separator
 );%0A 
@@ -3832,15 +3832,10 @@
 lace
-All(%22%5C%5C
+(%22
 %5C%5C%22,

Simplify file separator cleanup