package net.techcable.srglib.format;

import java.io.CharArrayReader;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.CharStreams;
import com.google.common.io.LineProcessor;
import com.google.common.io.LineReader;

import net.techcable.srglib.mappings.Mappings;
import net.techcable.srglib.utils.Exceptions;

import static net.techcable.srglib.utils.Exceptions.*;

/**
 * A format for serializing mappings to and from text.
 */
public interface MappingsFormat {
    MappingsFormat SEARGE_FORMAT = SrgMappingsFormat.INSTANCE;
    MappingsFormat COMPACT_SEARGE_FORMAT = CompactSrgMappingsFormat.INSTANCE;

    default Mappings parse(Readable readable) throws IOException {
        LineReader lineReader = new LineReader(readable);
        LineProcessor<Mappings> lineProcessor = createLineProcessor();
        String line;
        while ((line = lineReader.readLine()) != null) {
            if (!lineProcessor.processLine(line)) {
                break;
            }
        }
        return lineProcessor.getResult();
    }

    default Mappings parseLines(String... lines) {
        return parseLines(Arrays.asList(lines));
    }

    default Mappings parseLines(Iterable<String> lines) {
        return parseLines(lines.iterator());
    }

    default Mappings parseLines(Iterator<String> lines) {
        LineProcessor<Mappings> lineProcessor = createLineProcessor();
        lines.forEachRemaining(Exceptions.sneakyThrowing(lineProcessor::processLine));
        return lineProcessor.getResult();
    }

    LineProcessor<Mappings> createLineProcessor();

    void write(Mappings mappings, Appendable output) throws IOException;

    default List<String> toLines(Mappings mappings) {
        CharArrayWriter result = new CharArrayWriter();
        return sneakyThrowing(() -> {
            this.write(mappings, result);
            return CharStreams.readLines(new CharArrayReader(result.toCharArray()));
        }).get();
    }
}

@@ -27,24 +27,55 @@
 ib.format;%0A%0A
+import java.io.BufferedWriter;%0A
 import java.
@@ -141,27 +141,256 @@
 java.io.
-IOException
+File;%0Aimport java.io.FileInputStream;%0Aimport java.io.FileOutputStream;%0Aimport java.io.IOException;%0Aimport java.io.InputStreamReader;%0Aimport java.io.OutputStreamWriter;%0Aimport java.io.Reader;%0Aimport java.io.Writer;%0Aimport java.nio.file.Files
 ;%0Aimport
@@ -455,24 +455,64 @@
 util.List;%0A%0A
+import com.google.common.base.Charsets;%0A
 import com.g
@@ -1522,32 +1522,298 @@
 esult();%0A    %7D%0A%0A
+    default Mappings parseFile(File file) throws IOException %7B%0A        try (Reader in = new InputStreamReader(new FileInputStream(file), Charsets.UTF_8)) %7B%0A            // Don't worry, parse(Readable) buffers internally%0A            return parse(in);%0A        %7D%0A    %7D%0A%0A
     default Mapp
@@ -2404,16 +2404,263 @@
 ption;%0A%0A
+    default void writeToFile(Mappings mappings, File file) throws IOException %7B%0A        try (Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8))) %7B%0A            write(mappings, out);%0A        %7D%0A    %7D%0A%0A
     defa

Add utility methods that write to a file