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

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

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

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

    const baseUser = await createUser();
    const baseData = await realPayloadGenerator({}, baseUser);
    const basePayload = baseData.payload;
    console.log("user information created")

    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,
                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));

    //invalid haro ham dar yek araye zakhire kon

    //----------------------------------------------------------------------------------------

    for await (let key of Object.keys(allWorkFlowInfo)) {
        if (!allWorkFlowInfo[key].isValid) {
            console.log(`workflow with id:'${key}' in invalid`);
            delete allWorkFlowInfo[key];
        }
    }

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



    for await (const workflow of Object.keys(allWorkFlowInfo)) {
        if (workflow == 57) {
            const data = allWorkFlowInfo[workflow];
            const pathsCollection = data?.root?.validPaths || [];
            if (pathsCollection?.length == 0) allWorkFlowInfo[key].isValid = false;
            for await (let pathString of pathsCollection) {
                const pathCollection = pathString.split(",");

                let data = {}, pathTraveled = [];
                //inja masir start mishe

                for await (let path of pathCollection) {
                    const process = await bpmsDB.bpms_process.findByPk(path, { raw: true });
                    pathTraveled.push(+path);
                    console.log(path, process);
                    if ([0, 1].includes(+process.type)) {
                        const processData = await initFunctionData({
                            processId: process.id,
                            payload: basePayload
                        })
                        console.log("processedData",processData);
                        data = { ...data, ...processData.data };
                        console.log("data",data);
                    }
                    return;
                }

            }
            return;
        }
    }


    for await (let key of Object.keys(allWorkFlowInfo)) {
        if (!allWorkFlowInfo[key].isValid) {
            console.log(`workflow with id:'${key}' in invalid`);
            delete allWorkFlowInfo[key];
        }
    }
    console.timeEnd("WorkflowTester");
    console.log("DONE");
    process.exit(0);
})()