const path = require('path');
const fs = require('fs');

const { sleep, saveLargeObject } = require('./util');
const { getAllWorkflows } = require('./workflow');
const { getAllProcesses, getProcessPaths, getProcessPathsSubFlow } = require('./process');

require(path.join(process.cwd(), "..", "server", "dist", "database.js"));

(async function () {
    await sleep(5e3);
    console.time("WorkflowTester")

    console.log("initilizing begin..");

    const workflows = await getAllWorkflows({
        id: {
            [Op.gt]: 0
        }
    });
    if (workflows.length == 0) throw "There is not any workflow";

    const allWorkFlowInfo = {};

    workflowsFor:
    for await (const workflow of workflows) {

        if (+workflow.id < 0) continue;

        const processes = await getAllProcesses(workflow, {
            subFlowId: null,
        });

        if (processes.length == 0) {
            allWorkFlowInfo[workflow.id] = {
                isValid: false,
                root: {
                    valid: 0,
                    invalid: 0,
                    subFlowList: []
                },
                subFlow: {}
            }
            continue workflowsFor;
        }

        const { allPaths: tree, subFlowParentIds, invalidPathsWithoutEnding } = await getProcessPaths(processes, workflow);
        allWorkFlowInfo[workflow.id] = {
            isValid: invalidPathsWithoutEnding.length == 0 ? true : false,
            root: {
                validPaths: invalidPathsWithoutEnding.length == 0 && tree.length > 0 ? tree : [],
                // invalidPaths: invalidPathsWithoutEnding.length == 0?[]:invalidPathsWithoutEnding,
                valid: tree.length,
                invalid: invalidPathsWithoutEnding.length,
                subFlowList: subFlowParentIds
            },
            subFlow: {}
        }

        if (invalidPathsWithoutEnding.length > 0) {
            allWorkFlowInfo[workflow.id].isValid = false;
            continue workflowsFor;
        }

        const subFlowInfo = {}


        subFlowFor:
        for await (const subFlowId of subFlowParentIds) {
            const processesSubFlow = await getAllProcesses(workflow, {
                [Op.or]: [
                    {
                        subFlowId: subFlowId,
                    },
                    {
                        subFlowPid: subFlowId
                    }
                ]
            })

            if (processesSubFlow.length == 0) {
                allWorkFlowInfo[workflow.id].isValid = false;
                subFlowInfo[subFlowId] = {
                    valid: 0,
                    invalid: 0,
                    validSubTreePath: [],
                    invalidSubTreePath: [],
                    error: "این ورک فلو ساب آیدی ، هیچ زیرمجموعه ای ندارد"
                }
                continue subFlowFor;
            }

            const { subTreePath, invalidSubPathsWithoutEnding } = await getProcessPathsSubFlow(processesSubFlow, subFlowId, workflow);
            if (invalidSubPathsWithoutEnding.length > 0) {
                allWorkFlowInfo[workflow.id].isValid = false;
            }
            subFlowInfo[subFlowId] = {
                valid: subTreePath.length,
                invalid: invalidSubPathsWithoutEnding.length,
                // validSubTreePath: subTreePath,
                // invalidSubTreePath: invalidSubPathsWithoutEnding
            }
        }
        allWorkFlowInfo[workflow.id]["subFlow"] = subFlowInfo;

    }

    // console.log("allWorkFlowInfo", JSON.stringify(allWorkFlowInfo, null, 2));
    // fs.writeFileSync("./result-pretty.json", JSON.stringify(allWorkFlowInfo, null, 2));
    // await saveLargeObject(allWorkFlowInfo, "./result-pretty-beforeProcess.json")
    // fs.writeFileSync("./result-beforeProcess.json", JSON.stringify(allWorkFlowInfo));

    for await(let key of Object.keys(allWorkFlowInfo)){
        if (!allWorkFlowInfo[key].isValid) {
            delete allWorkFlowInfo[key];
        }
    }

    await saveLargeObject(allWorkFlowInfo, "./result-pretty-afterProcess.json")
    fs.writeFileSync("./result-afterProcess.json", JSON.stringify(allWorkFlowInfo));

    console.timeEnd("WorkflowTester");
    console.log("DONE");
    process.exit(0);
})()