package school_project.Parsers;

import javafx.util.Pair;
import school_project.Map;

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

/**
 * This is used to find the right parser to parser a save/level file.
 * This should be the only right way to save/load a file! you can just use `Map loadMapFromFile(File)` to load a file
 * and `void saveFileFromMap(File, Map)` to save a file
 *
 * <p>
 * there is currently 2 file format with 2 variation each (save file or level file)
 * - BinaryParser
 *  - ".level"
 *  - ".slevel"
 * - SerializeParser
 *  - ".serialized"
 *  - ".sserialized"
 * </p>
 *
 * <p>
 * More file format can be added in the future by adding a new class that implement parser
 * and adding it to this file
 * </p>
 *
 * @author tonitch
 */
public class FileParserFactory {
    /**
     * Load a file and return a map
     * If this is a save map, return the map with its save data
     * @param file file to get data from
     * @return Map generated from the file
     * @throws FileNotFoundException if the file was not found or was not accessible
     * @throws IOException if an I/O occurs
     */
    public static Map loadMapFromFile(File file) throws IOException {
        Pair<FileParser, Boolean> parser= getFileParser(file);
        return parser.getKey().getLevel(file, parser.getValue());
    }

    /**
     * Save a file in a specific format, this format is defined by the file extension
     * This file extention could be: ".level", ".slevel", ".serialized", ".sserialized"
     * for save file use the .s variations
     * @param file file name to be saved to with the right extension
     * @param map map file to save
     * @throws NotSerializableException the file extension is not recognised
     * @throws FileNotFoundException The file could not be created
     * @throws IOException if an I/O occurs
     */
    public static void saveFileFromMap(File file, Map map) throws IOException {
        Pair<FileParser, Boolean> parser= getFileParser(file);
        parser.getKey().saveLevel(file, map, parser.getValue());
    }

    private static Pair<FileParser, Boolean> getFileParser(File file) throws NotSerializableException {
        FileParser fileParser;
        boolean save_data;

        if (file.toString().toLowerCase().endsWith(".level")){
            fileParser = new BinaryParser();
            save_data = false;
        }else if(file.toString().toLowerCase().endsWith(".slevel")){
            fileParser = new BinaryParser();
            save_data = true;
        }else if(file.toString().toLowerCase().endsWith(".serialized")){
            fileParser = new SerializeParser();
            save_data = false;
        }else if(file.toString().toLowerCase().endsWith(".sserialized")) {
            fileParser = new SerializeParser();
            save_data = true;
        }else {
            throw new NotSerializableException("This file format is not supported");
        }
        return new Pair<FileParser, Boolean>(fileParser, save_data);
    }
}