<?php
/*
** Job Arranger Manager
** Copyright (C) 2023 Daiwa Institute of Research Ltd. All Rights Reserved.
**
** Licensed to the Apache Software Foundation (ASF) under one or more
** contributor license agreements. See the NOTICE file distributed with
** this work for additional information regarding copyright ownership.
** The ASF licenses this file to you under the Apache License, Version 2.0
** (the "License"); you may not use this file except in compliance with
** the License. You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
**
**/

namespace App\Controllers;

use App\Exceptions\InvalidScheduleDeleteException;
use Rakit\Validation\Validator;
use App\Models\JobExecutionManagementModel;
use App\Models\RunJobnetModel;
use App\Models\UserModel;
use App\Models\GeneralSettingModel;
use App\Utils\Controller;
use App\Utils\Core;
use App\Utils\Constants;
use App\Utils\Util;
use DateInterval;
use DateTime;
use DateTimeZone;
use PDOException;

/**
 * This controller is used to manage the Jobnet Execution Management.
 *
 * @version    6.1.0
 * @since      Class available since version 6.1.0
 */
class JobnetExecManagement extends Controller
{

    private $jobnetViewSpan = 0;
    /**
     * @var RunJobnetModel
     */
    private $runJobnetModel;
    /**
     * @var JobExecutionManagementModel
     */
    private $jobExecutionManagementModel;
    /**
     * @var Util
     */
    private $util;

    /**
     * @var Validator
     */
    private $validator;

    /**
     * @var UserModel
     */
    private $userModel;

    public function __construct()
    {
        parent::__construct();
        $this->runJobnetModel = new RunJobnetModel;
        $this->jobExecutionManagementModel = new JobExecutionManagementModel;
        $this->util = new Util;
        $this->userModel = new UserModel;
        $this->logger = Core::logger();
        $this->validator = new Validator();
    }

    /**
     * api endpoint that retrieves the all operation list
     *
     * @since   Method available since version 6.1.0
     */
    public function getAllOperationList()
    {
        $this->logger->info('Get all operation list process is started.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        try {
            $json = file_get_contents('php://input');
            $params = Util::jsonDecode($json)["params"];
            $validator = $this->validator;
            $validation = $this->validator->validate($params, [
                'timezone' => 'required',
                'date' => 'required',
            ]);
            if ($validation->fails()) {
                $errors = $validation->errors();
                return $errors;
            }
            $this->jobnetViewSpan = $this->runJobnetModel->getParameterData(Constants::JOBNET_VIEW_SPAN);
            $date = $params["date"];
            $timezone = $params["timezone"];

            $generalSettingModel = new GeneralSettingModel();
            $managerTimeSync = $generalSettingModel->getParameterValue("MANAGER_TIME_SYNC");
            if($managerTimeSync == 1){

                $serverTimezoneName = date_default_timezone_get();
                $serverTimezone = new DateTimeZone($serverTimezoneName);
                $now = new DateTime('now', $serverTimezone);
                $this->logger->info("Server time zone: " . $serverTimezoneName);
                $nowString = $now->getTimestamp();
                // $nowString = $this->util->getUnixTimeFromTimeZone($serverTimezoneName, $date);

            }else {
                $nowString = $this->util->getUnixTimeFromTimeZone($timezone, $date);
            }

            // $nowString = $this->util->getDate(); // Unix timestamp
            $this->logger->info("Now string ". $nowString);
 
            //$nowString = $this->util->getDate(); // Unix timestamp
            $this->logger->info("Current Date.". $nowString);
            // $this->logger->info("Get Date .". $nowString);
 
            $after = (new DateTime())->setTimestamp((int)$nowString);
            $after->add(new DateInterval('PT' . $this->jobnetViewSpan . 'M'));
 
            $before = (new DateTime())->setTimestamp((int)$nowString);
            $before->sub(new DateInterval('PT' . $this->jobnetViewSpan . 'M'));
 
            $fromTime = $before->getTimestamp();
            $toTime = $after->getTimestamp();
            $startFromTime = $before->getTimestamp();
            $startToTime = $after->getTimestamp();  
 
            $this->logger->info("From Time (Unix): " . $fromTime);
            $this->logger->info("To Time (Unix): " . $toTime);
            $this->logger->info("Start From Time (Unix): " . $startFromTime);
            $this->logger->info("Start To Time (Unix): " . $startToTime);

            $jobnetList = null;

            if ($_SESSION['userInfo']['userType'] == Constants::USER_TYPE_SUPER) {
                $jobnetList = $this->jobExecutionManagementModel->getJobnetSummaryForSuper($fromTime, $toTime, $startFromTime, $startToTime);
            } else {
                if ($_SESSION['userInfo']['hasUserGroup']) {
                    $userid = $_SESSION['userInfo']['userId'];
                    $usernames = $this->userModel->getUsernamesFromSameGroup($userid);
                    $jobnetList = $this->jobExecutionManagementModel->getJobnetSummaryForAll($fromTime, $toTime, $startFromTime, $startToTime, $usernames);
                } else {
                    $usernames = $this->userModel->getUsernames();
                    $jobnetList = $this->jobExecutionManagementModel->getJobnetSummaryForNotBelongGroup($fromTime, $toTime, $startFromTime, $startToTime,$usernames);
                }
            }
            echo Util::response(Constants::API_RESPONSE_TYPE_OK, [Constants::API_RESPONSE_DATA => $jobnetList]);
        } catch (PDOException $e) {
            echo Util::response(Constants::API_RESPONSE_TYPE_500, [Constants::API_RESPONSE_MESSAGE => Constants::SERVICE_INTERNAL_SERVER_ERROR]);
            $this->logger->error($e->getMessage(), ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        }
        $this->logger->info('Get all operation list process is finished.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
    }

    /**
     * api endpoint that retrieves the error operation list
     *
     * @since   Method available since version 6.1.0
     */
    public function getErrorOperationList()
    {
        $this->logger->info('Get error operation list process is started.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        try {

            $jobnetErrList = null;
            if ($_SESSION['userInfo']['userType'] == Constants::USER_TYPE_SUPER) {
                $jobnetErrList = $this->jobExecutionManagementModel->getJobnetErrSummaryForSuper();
            } else {
                $userid = $_SESSION['userInfo']['userId'];
                $usernames = $this->userModel->getUsernamesFromSameGroup($userid);
                $jobnetErrList = $this->jobExecutionManagementModel->getJobnetErrSummaryForAll($usernames);
            }
            echo Util::response(Constants::API_RESPONSE_TYPE_OK, [Constants::API_RESPONSE_DATA => $jobnetErrList]);
        } catch (PDOException $e) {
            echo Util::response(Constants::API_RESPONSE_TYPE_500, [Constants::API_RESPONSE_MESSAGE => Constants::SERVICE_INTERNAL_SERVER_ERROR]);
            $this->logger->error($e->getMessage(), ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        }
        $this->logger->info('Get error operation list process is finished.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
    }

    /**
     * api endpoint that retrieves the during operation list
     *
     * @since   Method available since version 6.1.0
     */
    public function getDuringOperationList()
    {
        $this->logger->info('Get during operation list process is started.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        try {

            $jobnetRunningList = null;
            if ($_SESSION['userInfo']['userType'] == Constants::USER_TYPE_SUPER) {
                $jobnetRunningList = $this->jobExecutionManagementModel->getJobnetRunningSummaryForSuper();
            } else {
                $userid = $_SESSION['userInfo']['userId'];
                $usernames = $this->userModel->getUsernamesFromSameGroup($userid);
                $jobnetRunningList = $this->jobExecutionManagementModel->getJobnetRunningSummaryForAll($usernames);
            }
            echo Util::response(Constants::API_RESPONSE_TYPE_OK, [Constants::API_RESPONSE_DATA => $jobnetRunningList]);
        } catch (PDOException $e) {
            echo Util::response(Constants::API_RESPONSE_TYPE_500, [Constants::API_RESPONSE_MESSAGE => Constants::SERVICE_INTERNAL_SERVER_ERROR]);
            $this->logger->error($e->getMessage(), ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        }
        $this->logger->info('Get during operation list process is finished.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
    }

    /**
     * api endpoint that stops execution of the all jobnet summary.
     *
     * @since   Method available since version 6.1.0
     */
    public function setAllJobnetSummaryStop()
    {
        $this->logger->info('Stop all jobnet summary process is started.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);

        try {

            $json = file_get_contents('php://input');

            $params = Util::jsonDecode($json)["params"];

            $validation = $this->validator->validate($params, [
                'innerJobnetIdList' => 'required',
                'statusList' => 'required'
            ]);

            if ($validation->fails()) {
                $errors = $validation->errors();
                echo Util::response(Constants::API_RESPONSE_TYPE_BAD_REQUEST, [Constants::API_RESPONSE_MESSAGE => $errors->firstOfAll()]);
                $this->logger->info(Constants::SERVICE_MESSAGE_VALIDATION_FAIL . implode(", ", $errors->firstOfAll()), ['controller' => __METHOD__]);
            } else {
                // Ensure that the innerJobnetIdList and statusList have the same number of elements
                if (count($params["innerJobnetIdList"]) !== count($params["statusList"])) {
                    throw new PDOException(Constants::SERVICE_MESSAGE_FAIL);
                }
                $this->beginTransaction();
                foreach ($params["innerJobnetIdList"] as $index => $innerJobnetId) {
                        //insert into run action table updated in Jaz2
                        $runActionParams = [];
                        $runActionParams["innerJobnetId"] = $innerJobnetId;
                        $runActionParams["actionFlag"] = Constants::RUN_ACTION_JOBNET_STOP;
                        if (!$this->runJobnetModel->insertRunAction($runActionParams)) {
                            throw new PDOException(Constants::SERVICE_MESSAGE_FAIL);
                        }
                }
                $this->commit();
                echo Util::response(Constants::API_RESPONSE_TYPE_OK, [Constants::API_RESPONSE_MESSAGE => Constants::API_RESPONSE_MESSAGE_OPERATION_SUCCESS]);
            }
        } catch (PDOException $e) {
            if ($this->db->inTransaction()) {
                $this->rollback();
            }
            echo Util::response(Constants::API_RESPONSE_TYPE_500, [Constants::API_RESPONSE_MESSAGE => Constants::SERVICE_INTERNAL_SERVER_ERROR]);
            $this->logger->error($e->getMessage(), ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        }
        $this->logger->info('Stop all jobnet summary process is finished.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
    }

    /**
     * api endpoint that stops execution of the error jobnet summary.
     *
     * @since   Method available since version 6.1.0
     */
    public function setErrorJobnetSummaryStop()
    {
        $this->logger->info('Stop error jobnet summary process is started.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);

        try {

            $json = file_get_contents('php://input');

            $params = Util::jsonDecode($json)["params"];

            $validation = $this->validator->validate($params, [
                'innerJobnetIdList' => 'required'
            ]);

            if ($validation->fails()) {
                $errors = $validation->errors();
                echo Util::response(Constants::API_RESPONSE_TYPE_BAD_REQUEST, [Constants::API_RESPONSE_MESSAGE => $errors->firstOfAll()]);
                $this->logger->info(Constants::SERVICE_MESSAGE_VALIDATION_FAIL . implode(", ", $errors->firstOfAll()), ['controller' => __METHOD__]);
            } else {
                $this->beginTransaction();
                foreach ($params["innerJobnetIdList"] as $innerJobnetId) {

                    //insert into run action table updated in Jaz2
                    $runActionParams = [];
                    $runActionParams["innerJobnetId"] = $innerJobnetId;
                    $runActionParams["actionFlag"] = Constants::RUN_ACTION_JOBNET_STOP;
                    if (!$this->runJobnetModel->insertRunAction($runActionParams)) {
                        throw new PDOException(Constants::SERVICE_MESSAGE_FAIL);
                    }
                }
                $this->commit();
                echo Util::response(Constants::API_RESPONSE_TYPE_OK, [Constants::API_RESPONSE_MESSAGE => Constants::API_RESPONSE_MESSAGE_OPERATION_SUCCESS]);
            }
        } catch (PDOException $e) {
            if ($this->db->inTransaction()) {
                $this->rollback();
            }
            echo Util::response(Constants::API_RESPONSE_TYPE_500, [Constants::API_RESPONSE_MESSAGE => Constants::SERVICE_INTERNAL_SERVER_ERROR]);
            $this->logger->error($e->getMessage(), ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        }
        $this->logger->info('Stop error jobnet summary process is finished.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
    }

    /**
     * api endpoint that stops execution of the during jobnet summary.
     *
     * @since   Method available since version 6.1.0
     */
    public function setDuringJobnetSummaryStop()
    {
        $this->logger->info('Stop during jobnet summary process is started.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);

        try {

            $json = file_get_contents('php://input');

            $params = Util::jsonDecode($json)["params"];

            $validation = $this->validator->validate($params, [
                'innerJobnetId' => 'required'
            ]);

            if ($validation->fails()) {
                $errors = $validation->errors();
                echo Util::response(Constants::API_RESPONSE_TYPE_BAD_REQUEST, [Constants::API_RESPONSE_MESSAGE => $errors->firstOfAll()]);
                $this->logger->info(Constants::SERVICE_MESSAGE_VALIDATION_FAIL . implode(", ", $errors->firstOfAll()), ['controller' => __METHOD__]);
            } else {
                $this->beginTransaction();
                foreach ($params["innerJobnetIdList"] as $innerJobnetId) {

                    //insert into run action table updated in Jaz2
                    $runActionParams = [];
                    $runActionParams["innerJobnetId"] = $innerJobnetId;
                    $runActionParams["actionFlag"] = Constants::RUN_ACTION_JOBNET_STOP;
                    if (!$this->runJobnetModel->insertRunAction($runActionParams)) {
                        throw new PDOException(Constants::SERVICE_MESSAGE_FAIL);
                    }
                }
                $this->commit();
                echo Util::response(Constants::API_RESPONSE_TYPE_OK, [Constants::API_RESPONSE_MESSAGE => Constants::API_RESPONSE_MESSAGE_OPERATION_SUCCESS]);
            }
        } catch (PDOException $e) {
            if ($this->db->inTransaction()) {
                $this->rollback();
            }
            echo Util::response(Constants::API_RESPONSE_TYPE_500, [Constants::API_RESPONSE_MESSAGE => Constants::SERVICE_INTERNAL_SERVER_ERROR]);
            $this->logger->error($e->getMessage(), ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        }
        $this->logger->info('Stop during jobnet summary process is finished.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
    }

    /**
     * api endpoint that holds execution of the jobnet summary.
     *
     * @since   Method available since version 6.1.0
     */
    public function setHoldJobnetSummary()
    {
        $this->logger->info('Hold jobnet summary process is started.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);

        try {

            $json = file_get_contents('php://input');

            $params = Util::jsonDecode($json)["params"];

            $validation = $this->validator->validate($params, [
                'innerJobnetIdList' => 'required'
            ]);

            if ($validation->fails()) {
                $errors = $validation->errors();
                echo Util::response(Constants::API_RESPONSE_TYPE_BAD_REQUEST, [Constants::API_RESPONSE_MESSAGE => $errors->firstOfAll()]);
                $this->logger->info(Constants::SERVICE_MESSAGE_VALIDATION_FAIL . implode(", ", $errors->firstOfAll()), ['controller' => __METHOD__]);
            } else {
                $this->beginTransaction();
                foreach ($params["innerJobnetIdList"] as $innerJobnetId) {
                
                    //insert into run action table updated in Jaz2
                    $runActionParams = [];
                    $runActionParams["innerJobnetId"] = $innerJobnetId;
                    $runActionParams["actionFlag"] = Constants::RUN_ACTION_JOBNET_HOLD;
                    if (!$this->runJobnetModel->insertRunAction($runActionParams)) {
                        throw new PDOException(Constants::SERVICE_MESSAGE_FAIL);
                    }
                }
                $this->commit();
                echo Util::response(Constants::API_RESPONSE_TYPE_OK, [Constants::API_RESPONSE_MESSAGE => Constants::API_RESPONSE_MESSAGE_OPERATION_SUCCESS]);
            }
        } catch (PDOException $e) {
            if ($this->db->inTransaction()) {
                $this->rollback();
            }
            echo Util::response(Constants::API_RESPONSE_TYPE_500, [Constants::API_RESPONSE_MESSAGE => Constants::SERVICE_INTERNAL_SERVER_ERROR]);
            $this->logger->error($e->getMessage(), ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        }
        $this->logger->info('Hold jobnet summary process is finished.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
    }

    /**
     * api endpoint that releases the hold jobnet summary.
     *
     * @since   Method available since version 6.1.0
     */
    public function setReleaseJobnetSummary()
    {
        $this->logger->info('Release jobnet summary process is started.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        try {

            $json = file_get_contents('php://input');

            $params = Util::jsonDecode($json)["params"];

            $validation = $this->validator->validate($params, [
                'innerJobnetIdList' => 'required'
            ]);

            if ($validation->fails()) {
                $errors = $validation->errors();
                echo Util::response(Constants::API_RESPONSE_TYPE_BAD_REQUEST, [Constants::API_RESPONSE_MESSAGE => $errors->firstOfAll()]);
                $this->logger->info(Constants::SERVICE_MESSAGE_VALIDATION_FAIL . implode(", ", $errors->firstOfAll()), ['controller' => __METHOD__]);
            } else {
                $this->beginTransaction();
                foreach ($params["innerJobnetIdList"] as $innerJobnetId) {
                    //insert into run action table updated in Jaz2
                    $runActionParams = [];
                    $runActionParams["innerJobnetId"] = $innerJobnetId;
                    $runActionParams["actionFlag"] = Constants::RUN_ACTION_JOBNET_UNHOLD;
                    if (!$this->runJobnetModel->insertRunAction($runActionParams)) {
                        throw new PDOException(Constants::SERVICE_MESSAGE_FAIL);
                    }
                }
                $this->commit();
                echo Util::response(Constants::API_RESPONSE_TYPE_OK, [Constants::API_RESPONSE_MESSAGE => Constants::API_RESPONSE_MESSAGE_OPERATION_SUCCESS]);
            }
        } catch (PDOException $e) {
            if ($this->db->inTransaction()) {
                $this->rollback();
            }
            echo Util::response(Constants::API_RESPONSE_TYPE_500, [Constants::API_RESPONSE_MESSAGE => Constants::SERVICE_INTERNAL_SERVER_ERROR]);
            $this->logger->error($e->getMessage(), ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        }
        $this->logger->info('Release jobnet summary process is finished.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
    }

    /**
     * api endpoint that check the schedule of the jobnet summary is valid or not
     *
     * @since   Method available since version 6.1.0
     */
    public function checkIsScheduleValid()
    {
        $this->logger->info('Check schedule jobnet summary process is started.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        try {

            $json = file_get_contents('php://input');

            $params = Util::jsonDecode($json)["params"];

            $validation = $this->validator->validate($params, [
                'scheduleIdList' => 'required'
            ]);

            if ($validation->fails()) {
                $errors = $validation->errors();
                echo Util::response(Constants::API_RESPONSE_TYPE_BAD_REQUEST, [Constants::API_RESPONSE_MESSAGE => $errors->firstOfAll()]);
                $this->logger->info(Constants::SERVICE_MESSAGE_VALIDATION_FAIL . implode(", ", $errors->firstOfAll()), ['controller' => __METHOD__]);
            } else {
                $isValid = false;
                foreach ($params["scheduleIdList"] as $scheduleId) {
                    if (!$this->jobExecutionManagementModel->getScheduleValid($scheduleId)) {
                        echo Util::response(Constants::API_RESPONSE_TYPE_OK, [Constants::API_RESPONSE_MESSAGE => Constants::SERVICE_VALID,'validScheduleId' => $scheduleId]);
                        $isValid = true;
                        break;
                    } 
                }
                if(!$isValid) {
                    echo Util::response(Constants::API_RESPONSE_TYPE_OK, [Constants::API_RESPONSE_MESSAGE => Constants::SERVICE_INVALID]);
                }
            }
        } catch (PDOException $e) {
            echo Util::response(Constants::API_RESPONSE_TYPE_500, [Constants::API_RESPONSE_MESSAGE => Constants::SERVICE_INTERNAL_SERVER_ERROR]);
            $this->logger->error($e->getMessage(), ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        }
        $this->logger->info('Check schedule jobnet summary process is finished.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
    }

    /**
     * api endpoint that deletes the schedule jobnet summary
     *
     * @since   Method available since version 6.1.0
     */
    public function deleteScheduleJobnetSummary()
    {
        $this->logger->info('Delete schedule jobnet summary process is started.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        try {

            $json = file_get_contents('php://input');

            $params = Util::jsonDecode($json)["params"];

            $validation = $this->validator->validate($params, [
                'innerJobnetIdList' => 'required',
                'scheduleIdList' => 'required'
            ]);

            if ($validation->fails()) {
                $errors = $validation->errors();
                echo Util::response(Constants::API_RESPONSE_TYPE_BAD_REQUEST, [Constants::API_RESPONSE_MESSAGE => $errors->firstOfAll()]);
                $this->logger->info(Constants::SERVICE_MESSAGE_VALIDATION_FAIL . implode(", ", $errors->firstOfAll()), ['controller' => __METHOD__]);
            } else {
                $isValid = false;
                foreach ($params["scheduleIdList"] as $scheduleId) {
                    if (!$this->jobExecutionManagementModel->getScheduleValid($scheduleId)) {
                        echo Util::response(Constants::API_RESPONSE_TYPE_INCOMPLETE, [Constants::API_RESPONSE_MESSAGE => $scheduleId . " schedule is enabled. Please delete the schedule after disabled it.", 'validScheduleId' => $scheduleId]);
                        $isValid = true;
                        break;
                    } 
                }
                foreach ($params["innerJobnetIdList"] as $innerJobnetId) {
                    foreach ($params["innerJobnetIdList"] as $innerJobnetId) {
                        if (!$this->jobExecutionManagementModel->getScheduleJobnet($innerJobnetId)) {
                            throw new InvalidScheduleDeleteException("Jobnet will run within 5 minutes. Verify that it has been executed.");
                        }
                    }  
                }
                if(!$isValid) {
                    $this->beginTransaction();
                    foreach ($params["innerJobnetIdList"] as $innerJobnetId) {
                        //insert into run action table updated in Jaz2
                        $runActionParams = [];
                        $runActionParams["innerJobnetId"] = $innerJobnetId;
                        $runActionParams["actionFlag"] = Constants::RUN_ACTION_SCHEDULE_DELETE;
                        if (!$this->runJobnetModel->insertRunAction($runActionParams)) {
                            throw new PDOException(Constants::SERVICE_MESSAGE_FAIL);
                        }
                    }                 
                    $this->commit();
                    echo Util::response(Constants::API_RESPONSE_TYPE_OK, [Constants::API_RESPONSE_MESSAGE => Constants::API_RESPONSE_MESSAGE_OPERATION_SUCCESS]); 
                }              
            }
        } catch (InvalidScheduleDeleteException $e) {
            if ($this->db->inTransaction()) {
                $this->rollback();
            }
            echo Util::response(Constants::API_RESPONSE_TYPE_INCOMPLETE, [Constants::API_RESPONSE_MESSAGE => $e->getMessage(), Constants::API_RESPONSE_MESSAGE_CODE => "err-msg-common-030"]);
            $this->logger->error($e->getMessage(), ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        } catch (PDOException $e) {
            if ($this->db->inTransaction()) {   
                $this->rollback();
            }
            echo Util::response(Constants::API_RESPONSE_TYPE_500, [Constants::API_RESPONSE_MESSAGE => Constants::SERVICE_INTERNAL_SERVER_ERROR]);
            $this->logger->error($e->getMessage(), ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        }
        $this->logger->info('Delete schedule jobnet summary process is finished.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
    }

    /**
     * api endpoint that updates the schedule jobnet summary
     *
     * @since   Method available since version 6.1.0
     */
    public function updateScheduleJobnetSummary()
    {
        $this->logger->info('Update schedule jobnet summary process is started.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        try {
            $json = file_get_contents('php://input');
            $params = Util::jsonDecode($json)["params"];

            $validation = $this->validator->validate($params, [
                'innerJobnetId' => 'required',
                'scheduleTime' => 'required',
                'timezone' => 'required',
                'date' => 'required'
            ]);

            if ($validation->fails()) {
                $errors = $validation->errors();
                echo Util::response(Constants::API_RESPONSE_TYPE_BAD_REQUEST, [Constants::API_RESPONSE_MESSAGE => $errors->firstOfAll()]);
                $this->logger->info(Constants::SERVICE_MESSAGE_VALIDATION_FAIL . implode(", ", $errors->firstOfAll()), ['controller' => __METHOD__]);
            } else {
                $innerJobnetId = $params["innerJobnetId"];

                $now = time();
                if ($params["scheduleTime"] <= $now) {
                    echo Util::response(Constants::API_RESPONSE_TYPE_BAD_REQUEST, [Constants::API_RESPONSE_MESSAGE => "Schedule time must not be past time."]);
                    $this->logger->info("Schedule time must not be past time.", ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
                } else {
                    $this->beginTransaction();
                    //insert into run action table updated in Jaz2
                    $runActionParams = [];
                    $runActionParams["innerJobnetId"] = $innerJobnetId;
                    $runActionParams["actionFlag"] = Constants::RUN_ACTION_SCHEDULE_UPDATE;
                    $runActionParams["scheduledTime"] = $params["scheduleTime"];
                    if (!$this->runJobnetModel->insertRunAction($runActionParams)) {
                        throw new PDOException(Constants::SERVICE_MESSAGE_FAIL);
                    }
                    $this->commit();
                    echo Util::response(Constants::API_RESPONSE_TYPE_OK, [Constants::API_RESPONSE_MESSAGE => Constants::API_RESPONSE_MESSAGE_OPERATION_SUCCESS]);
                }
            }
        } catch (PDOException $e) {
            if ($this->db->inTransaction()) {
                $this->rollback();
            }
            echo Util::response(Constants::API_RESPONSE_TYPE_500, [Constants::API_RESPONSE_MESSAGE => Constants::SERVICE_INTERNAL_SERVER_ERROR]);
            $this->logger->error($e->getMessage(), ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        }
        $this->logger->info('Update schedule jobnet summary process is finished.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
    }

    /**
     * api endpoint that delays the jobnet summary
     *
     * @since   Method available since version 6.1.0
     */
    public function delayJobnetSummary()
    {
        $this->logger->info('Delay jobnet summary process is started.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);

        try {

            $json = file_get_contents('php://input');
            $params = Util::jsonDecode($json)["params"];

            $validation = $this->validator->validate($params, [
                'innerJobnetIdList' => 'required',
                'loadStatusList' => 'required'
            ]);

            if ($validation->fails()) {
                $errors = $validation->errors();
                echo Util::response(Constants::API_RESPONSE_TYPE_BAD_REQUEST, [Constants::API_RESPONSE_MESSAGE => $errors->firstOfAll()]);
                $this->logger->info(Constants::SERVICE_MESSAGE_VALIDATION_FAIL . implode(", ", $errors->firstOfAll()), ['controller' => __METHOD__]);
            } else {
                // Ensure that the innerJobnetIdList and statusList have the same number of elements
                if (count($params["innerJobnetIdList"]) !== count($params["loadStatusList"])) {
                    throw new PDOException(Constants::SERVICE_MESSAGE_FAIL);
                }
                $this->beginTransaction();
                foreach ($params["innerJobnetIdList"] as $index => $innerJobnetId) {
                    $loadStatus = $params["loadStatusList"][$index];
                    if ($loadStatus == Constants::LOAD_STATUS_DELAY) {  
                        //insert into run action table updated in Jaz2
                        $runActionParams = [];
                        $runActionParams["innerJobnetId"] = $innerJobnetId;
                        $runActionParams["actionFlag"] = Constants::RUN_ACTION_DELAYED_START;
                        if (!$this->runJobnetModel->insertRunAction($runActionParams)) {
                            throw new PDOException(Constants::SERVICE_MESSAGE_FAIL);
                        } 
                    } 
                }
                $this->commit();
                echo Util::response(Constants::API_RESPONSE_TYPE_OK, [Constants::API_RESPONSE_MESSAGE => Constants::API_RESPONSE_MESSAGE_OPERATION_SUCCESS]);
            }
        } catch (PDOException $e) {
            if ($this->db->inTransaction()) {
                $this->rollback();
            }
            echo Util::response(Constants::API_RESPONSE_TYPE_500, [Constants::API_RESPONSE_MESSAGE => Constants::SERVICE_INTERNAL_SERVER_ERROR]);
            $this->logger->error($e->getMessage(), ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        }
        $this->logger->info('Delay jobnet summary process is finished.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
    }

    /**
     * It updates run jobnet status to delay.
     *
     * @param   int $innerJobnetId
     * @throws  PDOException
     * @return  string
     * @since   Method available since version 6.1.0
     */
    private function setJaRunJobnetTableStatus($innerJobnetId)
    {
        $this->logger->debug('Set run jobnet table status delay process is started.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        try {
            // $jobnetLoadSpan = $this->runJobnetModel->getParameterData(Constants::JOBNET_LOAD_SPAN);
            $runJobnetData = [
                "status" => Constants::RUN_JOB_STATUS_TYPE_NONE
            ];
            $runJobnetWhere = "inner_jobnet_id = $innerJobnetId";

            if (!$this->runJobnetModel->updateRunJobnetMethod($runJobnetData, $runJobnetWhere)) {
                throw new PDOException(Constants::SERVICE_MESSAGE_FAIL);
            }

            return Constants::SERVICE_MESSAGE_SUCCESS;
        } catch (PDOException $e) {
            throw new PDOException($e->getMessage());
        }
        $this->logger->debug('Set run jobnet table status process is finished.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
    }

    /**
     * It updates run jobnet summary status to dalay.
     *
     * @param   int $innerJobnetId
     * @throws  PDOException
     * @return  string
     * @since   Method available since version 6.1.0
     */
    private function setJaRunJobnetSummaryTableStatus($innerJobnetId)
    {
        $this->logger->debug('Set run jobnet summary table status to delay process is started.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        try {
            $runJobnetSummaryData = [
                "status" => Constants::RUN_JOB_STATUS_TYPE_PREPARE,
                "job_status" => Constants::RUN_JOB_OPERATION_STATUS_NORMAL,
                "load_status" => Constants::LOAD_STATUS_TYPE_NONE
            ];
            $runJobnetSummaryWhere = "inner_jobnet_id = $innerJobnetId";

            if (!$this->jobExecutionManagementModel->updateRunJobnetSummary($runJobnetSummaryData, $runJobnetSummaryWhere)) {
                throw new PDOException(Constants::SERVICE_MESSAGE_FAIL);
            }

            return Constants::SERVICE_MESSAGE_SUCCESS;
        } catch (PDOException $e) {
            throw new PDOException($e->getMessage());
        }
        $this->logger->debug('Set run jobnet summary table status to delay process is finished.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
    }

    /**
     * It updates run job status to dalay.
     *
     * @param   string $innerJobnetId
     * @throws  PDOException
     * @return  string
     * @since   Method available since version 6.1.0
     */
    private function setJaRunJobTableStatus($innerJobnetId)
    {
        $this->logger->debug('Set run job table status to delay process is started.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        try {
            $runJobData = [
                "status" => Constants::RUN_JOB_STATUS_TYPE_NONE
            ];
            $runJobWhere = "inner_jobnet_id = $innerJobnetId and job_type = " . Constants::ICON_TYPE_START;

            if (!$this->runJobnetModel->updateRunJobMethod($runJobData, $runJobWhere)) {
                throw new PDOException(Constants::SERVICE_MESSAGE_FAIL);
            }

            return Constants::SERVICE_MESSAGE_SUCCESS;
        } catch (PDOException $e) {
            throw new PDOException($e->getMessage());
        }
        $this->logger->debug('Set run job table status to delay process is finished.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
    }
}
