package cse.ucdenver.csci5593.parser;

import cse.ucdenver.csci5593.instruction.Instruction;

import java.io.*;
import java.util.*;

/**
 * Created by willi on 3/14/2016.
 */
public class Parser {

    private InstructionSet instSet;

    public Parser(InstructionSet instructionSet) {
        this.instSet = instructionSet;
    }

    /**
     * Parses a given file and returns a list of instructions
     * that can be used by a Core object to run
     *
     * @param filename
     * @return List of instructions generated by the file
     *         or null if the file isn't properly formatted
     * @see cse.ucdenver.csci5593.core.Core
     */
    public HashMap<Integer, Instruction> parseFile(String filename) {
        // Result
        HashMap<Integer, Instruction> result = new HashMap<>();
        int instructionIndex = this.instSet.maxRegisterIndex() + 1;

        // Loop through the file
        try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println("Parsing: " + line);
                line = line.trim();
                line = this.instSet.stripComments(line);
                if (line.isEmpty()) {
                    continue;
                }

                // Split the line at the spaces
                String[] splitLine = line.split("[\\t ]+");

                HashMap<Integer, Instruction> inst = this.instSet.generateInstructions(splitLine, instructionIndex);

                System.out.println("Adding: " + inst);

                if (inst != null) {
                    instructionIndex += inst.size();
                    result.putAll(inst);
                }

                System.out.println("\n\n");
            }
        } catch (FileNotFoundException e) {
            System.err.print("Parse file not found: " + filename);
        } catch (IOException e) {
            System.err.print("Error reading parse file: " + e);
        }

        System.out.println(result);

        return result;
    }
}
