package _VisualDVM.ComponentsServer.BugReport;
import Common.CommonConstants;
import Common.Database.Objects.DBObject;
import Common.Database.Objects.riDBObject;
import Common.Utils.TextLog;
import Common.Utils.Utils_;
import Common.Utils.Vector_;
import _VisualDVM.ComponentsServer.BugReportRecipient.BugReportRecipient;
import _VisualDVM.ComponentsServer.BugReportSetting.BugReportSetting;
import _VisualDVM.ComponentsServer.Component.ComponentType;
import _VisualDVM.ComponentsServer.UserAccount.UserAccount;
import _VisualDVM.Constants;
import _VisualDVM.Global;
import _VisualDVM.ProjectData.SapforData.SapforProperties;
import com.sun.org.glassfish.gmbal.Description;

import java.io.File;
import java.nio.file.Paths;
import java.util.Date;
import java.util.Vector;
public class BugReport extends riDBObject {
    //---
    public String project_version = "";
    public long visualiser_version = -1;
    public long sapfor_version = -1;
    public String comment = "";
    public Vector<BugReportSetting> settings = null;
    public Vector<BugReportRecipient> recipients = null;
    public String executor = "";
    @Description("DEFAULT ''")
    public String executor_address = "";
    public BugReportState state;
    public int percentage = 0;
    //-
    @Description("IGNORE")
    public String descriptionAdditionDraft = "";
    @Description("IGNORE")
    public String commentAdditionDraft = "";
    @Description("IGNORE")
    public File owner = null;
    @Description("IGNORE")
    public byte[] packed_archive = null;
    //--
    public long date = 0;
    public long change_date;
    //--
    public BugReport() {
    }
    public BugReport(BugReport src) {
        this.SynchronizeFields(src);
    }
    public BugReport(String sender_name_in, String sender_address_in, String description_in, String version_in) {
        id = CommonConstants.Nan;
        sender_name = sender_name_in;
        sender_address = sender_address_in;
        project_version = version_in;
        visualiser_version = Global.visualiser.version;
        sapfor_version = Global.components.get(ComponentType.Sapfor_F).version;
        settings = Global.mainModule.getProject().sapforProperties.toBugReportSettings();
        percentage = 0;
        description = description_in;
        date = new Date().getTime();
        change_date = new Date().getTime();
        state = BugReportState.draft;
        owner = Global.mainModule.getProject().Home;
    }
    @Override
    public void SynchronizeFields(DBObject src) {
        super.SynchronizeFields(src);
        BugReport b = (BugReport) src;
        change_date = b.change_date;
        description = b.description;
        comment = b.comment;
        state = b.state;
        percentage = b.percentage;
        //-
        executor = b.executor;
        executor_address = b.executor_address;
        project_version = b.project_version;
        visualiser_version = b.visualiser_version;
        sapfor_version = b.sapfor_version;
        descriptionAdditionDraft = b.descriptionAdditionDraft;
        commentAdditionDraft = b.commentAdditionDraft;
        owner = b.owner;
        change_date = b.change_date;
    }
    //--
    public File getHome() {
        return Utils_.getFile(System.getProperty("user.dir"), "BugReports", String.valueOf(id));
    }
    public File getArchiveFile() {
        return new File(getHome(),id + ".zip");
    }
    //--
    public String getDescriptionHeader() {
        if (description != null) {
            String[] data = description.split("\n");
            return (data.length > 0) ? data[0] : "";
        } else return "";
    }
    public boolean CheckNotDraft(TextLog log) {
        if (state.equals(BugReportState.draft)) {
            log.Writeln_("Отчёт об ошибке является черновиком");
            return false;
        }
        return true;
    }
    public String getMailTitlePrefix() {
        return "Ошибка " + Utils_.Brackets(id) + ", автор " + Utils_.Brackets(sender_name) + " : ";
    }
    public File[] getAttachements() {
        File[] project_attachements = Global.mainModule.getProject().getAttachmentsDirectory().listFiles();
        File[] res = new File[project_attachements.length + 1];
        res[0] = getArchiveFile();
        for (int i = 0; i < project_attachements.length; ++i)
            res[i + 1] = project_attachements[i];
        return res;
    }
    public boolean CheckDraft(TextLog log) {
        if (!state.equals(BugReportState.draft)) {
            log.Writeln("Отчёт об ошибке не является черновиком. Он уже опубликован");
            return false;
        }
        return true;
    }
    public String getNewMailText() {
        String res = String.join("\n",
                "Описание:", description, getPassport()
        );
        return res;
    }
    public String getSettingsSummary() {
        Vector<String> res = new Vector_<String>(
                (Global.mainModule.getAccount().isAdmin() ? ("Адрес отправителя: " + sender_address + "\n") : ""),
                "Версия SAPFOR: " + sapfor_version,
                "Версия визуализатора: " + visualiser_version,
                "----------------------------------"
        );
        //--
        Vector<BugReportSetting> settings_ = Global.componentsServer.db.getVectorByFK(this, BugReportSetting.class);
        SapforProperties dummy = new SapforProperties();
        for (BugReportSetting bugReportSetting : settings_)
            res.add(dummy.getFieldDescription(bugReportSetting.name) + "=" + Utils_.DQuotes(bugReportSetting.value));
        //--
        return String.join("\n", res);
    }
    public String getPassport() {
        return String.join("\n",
                Constants.separator,
                "Отправитель: " + sender_name,
                "Исполнитель: " + executor,
                "Проект: " + project_version,
                Constants.separator,
                getSettingsSummary(),
                Constants.separator);
    }
    public boolean isNoneProject() {
        return project_version.isEmpty();
    }
    //--->
    public void CheckRecipients() {
        Global.componentsServer.db.recipients.getUI().SelectAll(false);
        Vector<BugReportRecipient> recipients_ = state.equals(BugReportState.draft) ?
                recipients : Global.componentsServer.db.getVectorByFK(this, BugReportRecipient.class);
        if (recipients_ != null) {
            for (BugReportRecipient bugReportRecipient : recipients_) {
                if (Global.componentsServer.db.recipients.containsKey(bugReportRecipient.email))
                    Global.componentsServer.db.recipients.get(bugReportRecipient.email).Select(true);
            }
        }
    }
    public boolean canAppend(UserAccount account, TextLog log) {
        if (account.CheckRegistered(log)) {
            if (account.email.equals(sender_address) || account.email.equals(executor_address)) {
                return true;
            } else {
                switch (account.role) {
                    case Admin:
                    case Developer:
                        return true;
                    default:
                        if (log != null)
                            log.Writeln_("Вы не являетесь автором, исполнителем, разработчиком, или администратором");
                        return false;
                }
            }
        }
        return false;
    }
    public boolean canModify(UserAccount account, TextLog log) {
        if (account.CheckRegistered(log)) {
            switch (account.role) {
                case Admin:
                case Developer:
                    return true;
                default:
                    if (account.email.equals(sender_address)) return true;
                    if (log != null) log.Writeln_("Вы не являетесь автором, разработчиком, или администратором");
                    return false;
            }
        }
        return false;
    }
}
