package com.sleekbyte.tailor.output;

import com.sleekbyte.tailor.common.Location;
import com.sleekbyte.tailor.common.Messages;

import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * Generates and outputs formatted analysis messages for Xcode
 */
public class Printer implements AutoCloseable {

    private File inputFile;
    private HashMap<String, ViolationMessage> msgBuffer = new HashMap<String, ViolationMessage>();

    public Printer(File inputFile) {
        this.inputFile = inputFile;
    }

    /**
     * Prints warning message
     *
     * @param warningMsg warning message to print
     * @param location   location object containing line and column number for printing
     */
    public void warn(String warningMsg, Location location) {
        print(Messages.WARNING, warningMsg, location);
    }

    /**
     * Prints error message
     *
     * @param errorMsg error message to print
     * @param location location object containing line and column number for printing
     */
    public void error(String errorMsg, Location location) {
        print(Messages.ERROR, errorMsg, location);
    }

    private void print(String classification, String msg, Location location) {
        ViolationMessage violationMessage = new ViolationMessage("", -1, 0, "", "");
        try {
            violationMessage = new ViolationMessage(this.inputFile.getCanonicalPath(),
                                location.line,
                                location.column,
                                classification,
                                msg);

        } catch (IOException e) {
            System.err.println("Error in getting canonical path of input file: " + e.getMessage());
        }
        this.msgBuffer.put(violationMessage.toString(), violationMessage);
    }

    // Visible for testing only
    public static String genOutputStringForTest(String filePath, int line, String classification,
                                                String msg) {
        return filePath + ":" + line + ": " + classification + ": " + msg;
    }

    // Visible for testing only
    public static String genOutputStringForTest(String filePath, int line, int column, String classification,
                                                String msg) {
        return filePath + ":" + line + ":" + column + ": " + classification + ": " + msg;
    }

    @Override
    public void close() {
        flushBuffer();
    }

    private void flushBuffer() {

        ArrayList<ViolationMessage> outputList = new ArrayList<>();
        for(Map.Entry<String, ViolationMessage> map : msgBuffer.entrySet()){
            outputList.add(map.getValue());
        }
        Collections.sort(outputList);
        outputList.forEach(System.out::println);
        this.msgBuffer.clear();
    }
}

@@ -188,17 +188,126 @@
 va.util.
-*
+ArrayList;%0Aimport java.util.Collections;%0Aimport java.util.HashMap;%0Aimport java.util.List;%0Aimport java.util.Map
 ;%0A%0A/**%0A 
@@ -461,20 +461,16 @@
 private 
-Hash
 Map%3CStri
@@ -519,32 +519,8 @@
 Map%3C
-String, ViolationMessage
 %3E();
@@ -1484,87 +1484,23 @@
 h(),
-%0A                                location.line,%0A                               
+ location.line,
  loc
@@ -1533,28 +1533,16 @@
         
-    
-        
 classifi
@@ -1552,40 +1552,8 @@
 ion,
-%0A                               
  msg
@@ -1915,56 +1915,8 @@
 ion,
-%0A                                               
  Str
@@ -2361,263 +2361,86 @@
     
-flushBuffer();%0A    %7D%0A%0A    private void flushBuffer() %7B%0A%0A        ArrayList%3CViolationMessage%3E outputList = new ArrayList%3C%3E();%0A        for(Map.Entry%3CString, ViolationMessage%3E map : msgBuffer.entrySet())%7B%0A            outputList.add(map.getV
+List%3CViolationMessage%3E outputList = new ArrayList%3C%3E(this.msgBuffer.v
 alue
+s
 ());%0A
-        %7D%0A
     

Tweak code style in Printer