package _VisualDVM.Passes.All;
import Common.Utils.Utils_;
import Common.Visual.Windows.Dialog.Text.ComboTextDialog;
import _VisualDVM.ComponentsServer.Component.Sapfor.Sapfor;
import _VisualDVM.ComponentsServer.Component.Sapfor.TransformationPermission;
import _VisualDVM.Passes.PassCode;
import _VisualDVM.Passes.Sapfor.Transformation;
import _VisualDVM.ProjectData.Files.DBProjectFile;
import _VisualDVM.Utils;
import _VisualDVM.Visual.Windows.CombineFilesDialog;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Vector;
public class CombineFiles extends Transformation {
    protected File result = null;
    ComboTextDialog fd = null;
    @Override
    protected PassCode necessary() {
        return PassCode.SPF_GetIncludeDependencies;
    }
    @Override
    protected boolean canStart(Object... args) throws Exception {
        switch (Sapfor.transformationPermission) {
            case All:
                return super.canStart(args) && target.CheckSameStyle(Log) &&
                        (fd = new CombineFilesDialog()).ShowDialog("Выберите имя итогового файла", target.files_order);
            case VariantsOnly:
                if (getPermission().equals(TransformationPermission.VariantsOnly)) {
                    return super.canStart(args) && target.CheckSameStyle(Log) && (
                            (fd = new CombineFilesDialog()).ShowDialog("Выберите имя итогового файла", target.files_order)
                    );
                } else {
                    Log.Writeln_("Разрешено только построение параллельных вариантов!");
                    return false;
                }
            case None:
                Log.Writeln_("Нет разрешения на выполнение преобразований");
                return false;
        }
        return false;
    }
    //правила инклудов https://docs.oracle.com/cd/E19957-01/805-4939/6j4m0vna1/index.html
    @Override
    protected void body() throws Exception {
        result = Paths.get(target.last_version.Home.getAbsolutePath(),
                Utils_.isWindows() ? fd.Result : Utils_.toU(fd.Result)).toFile();
        //-----------------------
        //получить список хедеров.
        //-----------------------
        Vector<String> result_lines = new Vector<>();
        Vector<String> all_includes = new Vector<>();
        //-----------------------------
        result_lines.add("!-Found " + target.allIncludes.size() + " headers");
        System.out.println("found " + target.allIncludes.size() + " headers");
        for (String name : target.allIncludes) {
            all_includes.add("      include " + Utils_.Quotes(Utils_.toU(name))); //---
            result_lines.add("!      include " + Utils_.Quotes(Utils_.toU(name)));
        }
        result_lines.add("!-Collapse-" + target.files_order.size() + " files");
        int i = 1;
        for (String name : target.files_order) {
            result_lines.add("! -- " + i + ". " + Utils_.Brackets(name));
            ++i;
        }
        result_lines.add("!--------------------");
        for (String name : target.files_order) {
            //если есть инклуды начинаем мучиться.
            if (target.addictedFiles.containsKey(name)) {
                DBProjectFile file = target.db.files.Data.get(name);
                //---------------------------------------------------->>>
                List<String> file_lines = FileUtils.readLines(file.file);
                for (String line : file_lines) {
                    String header = Utils.extractHeaderName(line);
                    if (header != null) {
                        if (file.dependencies.contains(header))
                            result_lines.add("      include " + Utils_.Quotes(Utils_.toU(header)));
                    } else
                        result_lines.add(line);
                }
            } else {
                //инклудов нет. добавляем все подряд.
                result_lines.addAll(FileUtils.readLines(target.db.files.Data.get(name).file));
            }
        }
        FileUtils.writeLines(result, result_lines, false);
        //-------------------------------
        //теперь скопировать остальные файлы
        for (String name : target.db.files.Data.keySet()) {
            if (!target.files_order.contains(name)) {
                Files.copy(
                        target.db.files.Data.get(name).file.toPath(),
                        Paths.get(target.last_version.Home.getAbsolutePath(), name)
                );
            }
        }
    }
}
