package metalexer;

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

import metalexer.ast.Component;
import metalexer.ast.Layout;

public class FileLoader {
    private final List<FileLoaderHelper> helpers;

    private final Map<String, Component> components;
    private final Map<String, Layout> layouts;

    public FileLoader(String dir) {
        this(Collections.singletonList(dir));
    }

    public FileLoader(List<String> dirs) {
        this.helpers = new ArrayList<FileLoaderHelper>(dirs.size());

        for(String dir : dirs) {
            helpers.add(new FileLoaderHelper(dir));
        }

        this.components = new HashMap<String, Component>();
        this.layouts = new HashMap<String, Layout>();
    }

    public Component loadComponent(String compName, /*out*/ SortedSet<CompilationProblem> errors) throws IOException {
        if(components.containsKey(compName)) {
            //NB: won't re-add errors
            return components.get(compName);
        }
        for(FileLoaderHelper helper : helpers) {
            try {
                SortedSet<CompilationProblem> helperErrors = new TreeSet<CompilationProblem>();
                Component comp = helper.loadComponent(compName, errors);
                if(comp != null) {
                    errors.addAll(helperErrors);
                    components.put(compName, comp);
                    return comp;
                }
            } catch(FileNotFoundException e) {
                //do nothing - just try the next helper
            }
        }
        components.put(compName, null);
        return null;
    }

    public Layout loadLayout(String layoutName, /*out*/ SortedSet<CompilationProblem> errors) throws IOException {
        if(layouts.containsKey(layoutName)) {
            //NB: won't re-add errors
            return layouts.get(layoutName);
        }
        for(FileLoaderHelper helper : helpers) {
            try {
                SortedSet<CompilationProblem> helperErrors = new TreeSet<CompilationProblem>();
                Layout layout = helper.loadLayout(layoutName, errors);
                if(layout != null) {
                    errors.addAll(helperErrors);
                    layouts.put(layoutName, layout);
                    return layout;
                }
            } catch(FileNotFoundException e) {
                //do nothing - just try the next helper
            }
        }
        layouts.put(layoutName, null);
        return null;
    }
}
