package pl.pkk82.filehierarchygenerator;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import pl.pkk82.filehierarchygenerator.util.TempWorkingDirectoryCreator;

public class FileHierarchyGenerator {

	private Path currentDirectory;
	private Path currentFile;
	private final TempWorkingDirectoryCreator tempWorkingDirectoryCreatorM;
	private final List<Path> directoriesToCreate;
	private final List<Path> filesToCreate;
	private final Map<Path, List<String>> fileLines;
	private int level;

	public static FileHierarchyGenerator createRootDirectory(String rootDirectoryName) {
		return new FileHierarchyGenerator(rootDirectoryName);
	}

	public FileHierarchy generate() {
		try {
			Path tempWorkingDirectory = tempWorkingDirectoryCreatorM.createTempWorkingDirectory();
			Path rootDirectory = createDirectories(tempWorkingDirectory);
			createFiles(tempWorkingDirectory);
			return new FileHierarchy(rootDirectory);
		} catch (IOException e) {
			throw new FileHierarchyGeneratorException(e);
		}

	}

	public FileHierarchyGenerator directory(String directoryName) {
		Path newCurrentDirectory = currentDirectory.resolve(directoryName);
		directoriesToCreate.add(newCurrentDirectory);
		currentDirectory = newCurrentDirectory;
		level++;
		return this;
	}

	public FileHierarchyGenerator up() {
		validateLevel();
		level--;
		currentDirectory = currentDirectory.getParent();
		return this;
	}

	public FileHierarchyGenerator file(String fileName) {
		Path filePath = currentDirectory.resolve(fileName);
		currentFile = filePath;
		filesToCreate.add(filePath);
		return this;
	}

	public FileHierarchyGenerator line(String line) {
		if (currentFile == null) {
			throw new IllegalInvocationException("line method should not be invoked in current context (directory)");
		}
		if (!fileLines.containsKey(currentFile)) {
			fileLines.put(currentFile, new ArrayList<String>());
		}
		List<String> lines = fileLines.get(currentFile);
		lines.add(line);
		return this;
	}

	private FileHierarchyGenerator(String rootDirectoryName) {
		directoriesToCreate = new ArrayList<>();
		filesToCreate = new ArrayList<>();
		fileLines = new HashMap<>();
		level = 0;
		currentDirectory = Paths.get(rootDirectoryName);
		directoriesToCreate.add(currentDirectory);
		tempWorkingDirectoryCreatorM = new TempWorkingDirectoryCreator();
	}

	private Path createDirectories(Path tempWorkingDirectory) throws IOException {
		Path rootDirectory = null;
		for (Path directoryToCreate : directoriesToCreate) {
			Path fullPathToResolve = tempWorkingDirectory.resolve(directoryToCreate);
			Path createdDirectory = Files.createDirectories(fullPathToResolve);
			if (rootDirectory == null) {
				rootDirectory = createdDirectory;
			}
		}
		return rootDirectory;
	}

	private void createFiles(Path tempWorkingDirectory) throws IOException {
		for (Path fileToCreate : filesToCreate) {
			Path fullPathToResolve = tempWorkingDirectory.resolve(fileToCreate);
			Files.createFile(fullPathToResolve);
			if (fileLines.containsKey(fileToCreate)) {
				List<String> lines = fileLines.get(fileToCreate);
				Files.write(fullPathToResolve, lines, Charset.forName("utf8"));
			}
		}
	}

	private void validateLevel() {
		if (level - 1 < 0) {
			throw new IllegalInvocationException("up method should not be invoked in current context (root directory)");
		}
	}


}

@@ -521,17 +521,16 @@
 yCreator
-M
 ;%0A%09priva
@@ -929,17 +929,16 @@
 yCreator
-M
 .createT
@@ -2467,17 +2467,16 @@
 yCreator
-M
  = new T

Correct field name.