package TestingSystem.Group;
import Common.Current;
import Common.Global;
import Common.Utils.Utils;
import ProjectData.Files.DBProjectFile;
import ProjectData.LanguageName;
import ProjectData.Project.db_project_info;

import java.io.File;
import java.nio.file.Paths;
import java.util.LinkedHashMap;
import java.util.Vector;
//dynamic cats возможен через рефлексию.
//https://stackoverflow.com/questions/2127318/java-how-can-i-do-dynamic-casting-of-a-variable-from-one-type-to-another
public class GroupInterface {
    //-
    public static boolean filterMyOnly = false;
    //--
    public static boolean isVisible(Group object) {
        return (!filterMyOnly || Current.getAccount().email.equals(object.sender_address)) &&
                Global.testingServer.db.groups.applyFilters(object);
    }
    public static String getStyleOptions(DBProjectFile program) {
        if (program.languageName == LanguageName.fortran) {
            switch (program.style) {
                case fixed:
                case extended:
                    return "-FI";
                case free:
                    return "-f90";
                case none:
                    break;
            }
        }
        return "";
    }
    public static String getLanguageCompileCommand(LanguageName language) {
        switch (language) {
            case fortran:
                return "f";
            case c:
                return "c";
        }
        return "";
    }
    public static String getLanguageLinkCommand(LanguageName language) {
        switch (language) {
            case fortran:
                return "flink";
            case c:
                return "clink";
        }
        return "";
    }
    public static void generateForLanguage(
            String dvm_drv,
            LinkedHashMap<LanguageName, Vector<DBProjectFile>> programs,
            LanguageName language,
            Vector<String> titles,
            Vector<String> objects,
            Vector<String> bodies,
            String flags_in
    ) {
        if (!programs.get(language).isEmpty()) {
            String LANG_ = language.toString().toUpperCase() + "_";
            Vector<String> module_objects = new Vector<>();
            String module_body = "";
            int i = 1;
            for (DBProjectFile program : programs.get(language)) {
                //--
                program.last_assembly_name = language + "_" + i + ".o";
                String object = Utils.DQuotes(program.last_assembly_name);
                module_objects.add(object);
                module_body +=
                        object + ":\n" +
                                "\t" +
                                String.join(" ",
                                        Utils.MFVar(LANG_ + "COMMAND"),
                                        Utils.MFVar(LANG_ + "FLAGS"),
                                        getStyleOptions(program),
                                        "-c",
                                        program.getQSourceName(),
                                        "-o",
                                        object + "\n\n"
                                );
                ++i;
            }
            titles.add(String.join("\n",
                    LANG_ + "COMMAND=" + Utils.DQuotes(dvm_drv) + " " +
                            getLanguageCompileCommand(language),
                    LANG_ + "FLAGS=" + flags_in,
                    LANG_ + "OBJECTS=" + String.join(" ", module_objects),
                    ""
            ));
            objects.add(Utils.MFVar(LANG_ + "OBJECTS"));
            bodies.add(module_body);
        }
    }
    public static String GenerateMakefile(Group object, db_project_info project, String dvm_drv, String flags_in) {
        //----->>
        LinkedHashMap<LanguageName, Vector<DBProjectFile>> programs = project.getPrograms();
        Vector<String> titles = new Vector<>();
        Vector<String> objects = new Vector<>();
        Vector<String> bodies = new Vector<>();
        String binary = Utils.DQuotes("0");
        //----->>
        generateForLanguage(dvm_drv, programs, object.language, titles, objects, bodies, flags_in);
        //----->>
        return String.join("\n",
                "LINK_COMMAND=" + Utils.DQuotes(dvm_drv) + " " +
                        getLanguageLinkCommand(object.language),
                "LINK_FLAGS=" + flags_in + "\n",
                String.join("\n", titles),
                "all: " + binary,
                binary + " : " + String.join(" ", objects),
                "\t" + Utils.MFVar("LINK_COMMAND") + " " + Utils.MFVar("LINK_FLAGS") + " " + String.join(" ", objects) + " -o " + binary,
                String.join(" ", bodies));
    }
    //--
    public static void CopyFields(Group src, Group dst) {
        dst.description = src.description;
        dst.type = src.type;
        dst.language = src.language;
    }
    public static String getSummary(Group group) {
        return group.description + " " + group.language.getDescription();
    }
    //для тестирования Сапфора на локальной машине.
    public static File getLocalWorkspaceD(Group group){
        return Paths.get(Global.visualiser.getWorkspace().getAbsolutePath(), group.id).toFile();
    }
}
