<?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\Models;

use App\Utils\Constants;
use App\Utils\Model;

/**
 * This model is used to manage the jobnet execution management.
 *
 * @version    6.1.0
 * @since      Class available since version 6.1.0
 */
class JobExecutionManagementModel extends Model
{

    public function __construct()
    {
        parent::__construct();
        $this->dbUtilModel = new DbUtilModel();
    }

    /**
     * It retrieve the current system time.
     *
     * @return  string
     * @since   Method available since version 6.1.0
     */
    public function getSysTime()
    {
        $this->db->query("SELECT CURRENT_TIMESTAMP AS systemtime");

        return $this->db->single()->systemtime;
    }

    /**
     * It retrieve the valid schedule data
     *
     * @param   string $scheduleId  id of the schedule.
     * @return  string
     * @since   Method available since version 6.1.0
     */
    public function getScheduleValid($scheduleId)
    {
        $this->db->query("select * from ja_2_schedule_control_table where schedule_id = '$scheduleId' and valid_flag=1");

        if (count($this->db->resultSet()) == 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * It retrieve the valid schedule data
     *
     * @param   string $innerJobnetId  inner jobnet id of the run jobnet.
     * @return  bool
     * @since   Method available since version 6.1.0
     */
    public function getScheduleJobnet($innerJobnetId)
    {
        $this->db->query("select count(*) as count from ja_2_run_jobnet_table where inner_jobnet_main_id='$innerJobnetId' and main_flag=0 and status=0");

        $count = $this->db->single();

        if ($count->count > 0) {
            if (DATA_SOURCE_NAME == Constants::DB_MYSQL) {
                $this->db->query("SELECT *
                    FROM ja_2_run_jobnet_table
                    WHERE inner_jobnet_main_id = '$innerJobnetId'
                    AND scheduled_time > UNIX_TIMESTAMP(NOW() + INTERVAL 5 MINUTE)");
            }else{
                $this->db->query("SELECT *
                    FROM ja_2_run_jobnet_table
                    WHERE inner_jobnet_main_id = '$innerJobnetId'
                    AND scheduled_time > EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP + INTERVAL '5 minutes'))");
            }
            if ($this->db->execute()) {
                if($this->db->rowCount() > 0){
                    return true;
                }else{
                    return false;
                }
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    /**
     * It retrieve the jobnet summary data for Super Administrator.
     *
     * @param   string $fromTime (YmdHi)
     * @param   string $toTime (YmdHi)
     * @param   string $startFromTime (YmdHis)
     * @param   string $startToTime (YmdHis)
     * @return  array
     * @since   Method available since version 6.1.0
     */
    public function getJobnetSummaryForSuper($fromTime, $toTime, $startFromTime, $startToTime)
    {
        $query = "
            SELECT JR.* 
            FROM ja_2_run_jobnet_summary_table AS JR 
            WHERE (((JR.scheduled_time between $fromTime and $toTime) 
            OR (JR.start_time between $startFromTime and $startToTime) 
            OR ((JR.scheduled_time = 0) 
            and (JR.start_time between $startFromTime and $startToTime)) 
            OR ((JR.scheduled_time = 0) 
            and (JR.start_time = 0) 
            and (multiple_start_up = 2))) 
            or start_pending_flag = 1) 
            AND delete_flag = 0 
        UNION 
            select JR2.* from ja_2_ran_jobnet_summary_table AS JR2 
            where (((JR2.scheduled_time between $fromTime and $toTime) 
            OR (JR2.start_time between $startFromTime and $startToTime) 
            OR ((JR2.scheduled_time = 0) 
            and (JR2.start_time between $startFromTime and $startToTime)) 
            OR ((JR2.scheduled_time = 0) 
            and (JR2.start_time = 0) 
            and (multiple_start_up = 2))) 
            or start_pending_flag = 1) 
            AND delete_flag = 0 
        order by scheduled_time,start_time,inner_jobnet_id";
        $this->db->query($query);

        return $this->db->resultSet();
    }

    /**
     * It retrieve the jobnet summary data for all other users
     *
     * @param   string $fromTime (YmdHi)
     * @param   string $toTime (YmdHi)
     * @param   string $startFromTime (YmdHis)
     * @param   string $startToTime (YmdHis)
     * @param   array $usernames array of user which are in same group
     * @return  array
     * @since   Method available since version 6.1.0
     */
    public function getJobnetSummaryForAll($fromTime, $toTime, $startFromTime, $startToTime, array $usernames)
    {
        $placeholders = "'" . implode("','", $usernames) . "'";
        $sql1 = "
            SELECT JR.* 
            FROM ja_2_run_jobnet_summary_table AS JR 
            WHERE 
                ( 
                    (JR.scheduled_time BETWEEN $fromTime AND $toTime) OR 
                    (JR.start_time BETWEEN $startFromTime AND $startToTime) OR
                    (JR.scheduled_time = 0 AND JR.start_time BETWEEN $startFromTime AND $startToTime) OR
                    (JR.scheduled_time = 0 AND JR.start_time = 0 AND JR.multiple_start_up = 2) 
                )
                AND JR.public_flag = 1  
                AND JR.delete_flag = 0 
            UNION
            SELECT JR2.* 
            FROM ja_2_ran_jobnet_summary_table AS JR2 
            WHERE 
                ( 
                    (JR2.scheduled_time BETWEEN $fromTime AND $toTime) OR 
                    (JR2.start_time BETWEEN $startFromTime AND $startToTime) OR
                    (JR2.scheduled_time = 0 AND JR2.start_time BETWEEN $startFromTime AND $startToTime) OR
                    (JR2.scheduled_time = 0 AND JR2.start_time = 0 AND JR2.multiple_start_up = 2) 
                )
            AND JR2.public_flag = 1  
            AND JR2.delete_flag = 0
        ";

        $sql2 = "
            SELECT JR.*
            FROM ja_2_run_jobnet_summary_table AS JR 
            WHERE
                (
                    (JR.scheduled_time BETWEEN $fromTime AND $toTime) OR 
                    (JR.start_time BETWEEN $startFromTime AND $startToTime) OR
                    (JR.scheduled_time = 0 AND JR.start_time BETWEEN $startFromTime AND $startToTime) OR
                    (JR.scheduled_time = 0 AND JR.start_time = 0 AND JR.multiple_start_up = 2) 
                )
            AND JR.public_flag = 0 
            AND JR.delete_flag = 0 
            AND JR.user_name IN($placeholders)
            OR 
            (
                JR.start_pending_flag = 1 
                AND JR.delete_flag = 0 
            ) 
            UNION 
            SELECT JR2.*
            FROM ja_2_ran_jobnet_summary_table AS JR2 
            WHERE
                (
                    (JR2.scheduled_time BETWEEN $fromTime AND $toTime) OR 
                    (JR2.start_time BETWEEN $startFromTime AND $startToTime) OR
                    (JR2.scheduled_time = 0 AND JR2.start_time BETWEEN $startFromTime AND $startToTime) OR
                    (JR2.scheduled_time = 0 AND JR2.start_time = 0 AND JR2.multiple_start_up = 2) 
                )
            AND JR2.public_flag = 0 
            AND JR2.delete_flag = 0 
            AND JR2.user_name IN($placeholders)
            OR 
            (
                JR2.start_pending_flag = 1 
                AND JR2.delete_flag = 0 
            ) 
        ";

        $sql3 = "
            SELECT JR.* 
            FROM ja_2_run_jobnet_summary_table AS JR 
            WHERE 
                JR.start_pending_flag = 1 
                AND JR.public_flag = 1 
                AND JR.delete_flag = 0 
            UNION 
            SELECT JR2.* 
            FROM ja_2_ran_jobnet_summary_table AS JR2 
            WHERE 
                JR2.start_pending_flag = 1 
                AND JR2.public_flag = 1 
                AND JR2.delete_flag = 0 
        ";

        $mainSql = "
            SELECT JRAll.*
            FROM
            (
                ($sql1) 
                UNION
                ($sql2) 
                UNION
                ($sql3) 
            ) AS JRAll 
            ORDER BY JRAll.scheduled_time, JRAll.start_time, JRAll.inner_jobnet_id";
        $this->db->query($mainSql);
        return $this->db->resultSet();
    }

    /**
     * It retrieves the error jobnet summary for Super Administrator.
     *
     * @return  array
     * @since   Method available since version 6.1.0
     */
    public function getJobnetErrSummaryForSuper()
    {
        $query = "
            SELECT JR.* FROM
            ja_2_run_jobnet_summary_table AS JR
            WHERE
                JR.job_status=2  
                AND (JR.status In(2,4,5))  
                AND JR.delete_flag = 0 
            UNION 
            SELECT JR2.* FROM 
            ja_2_ran_jobnet_summary_table AS JR2
            WHERE
                JR2.job_status=2  
                AND (JR2.status In(2,4,5))  
                AND JR2.delete_flag = 0
            ORDER BY start_time desc,inner_jobnet_id desc
            ";
        $this->db->query($query);

        return $this->db->resultSet();
    }

    /**
     * It retrieves the error jobnet summary for all other users.
     *
     * @param   array $usernames array of user which are in same group
     * @return  array
     * @since   Method available since version 6.1.0
     */
    public function getJobnetErrSummaryForAll(array $usernames)
    {
        $placeholders = "'" . implode("','", $usernames) . "'";
        $sql1 = "
        SELECT JR.* FROM
        ja_2_run_jobnet_summary_table AS JR
        WHERE
            JR.job_status=2  
            AND (JR.status In(2,4,5))  
            AND JR.delete_flag = 0 
            AND JR.public_flag = 1 
        UNION 
        SELECT JR2.* FROM 
        ja_2_ran_jobnet_summary_table AS JR2
        WHERE
            JR2.job_status=2  
            AND (JR2.status In(2,4,5))  
            AND JR2.delete_flag = 0  
            AND JR2.public_flag = 1 
        ";

        $sql2 = "
        SELECT JR.* FROM
        ja_2_run_jobnet_summary_table AS JR
        WHERE
            JR.job_status=2  
            AND (JR.status In(2,4,5))  
            AND JR.delete_flag = 0 
            AND JR.public_flag = 0 
            AND JR.user_name IN ($placeholders) 
        UNION
        SELECT JR2.* FROM
        ja_2_ran_jobnet_summary_table AS JR2
        WHERE
            JR2.job_status=2  
            AND (JR2.status In(2,4,5))  
            AND JR2.delete_flag = 0 
            AND JR2.public_flag = 0 
            AND JR2.user_name IN ($placeholders) 
        ";

        $mainSql = "
        SELECT JRAll.*
        FROM
        (
            ($sql1) 
            UNION
            ($sql2)
        ) AS JRAll 
        ORDER BY JRAll.start_time DESC, JRAll.inner_jobnet_id DESC";
        $this->db->query($mainSql);
        
        return $this->db->resultSet();
    }

    /**
     * It retrieves the running jobnet summary for Super Administrator.
     *
     * @return  string
     * @since   Method available since version 6.1.0
     */
    public function getJobnetRunningSummaryForSuper()
    {
        $query ="
        SELECT JR.*
        FROM
        ja_2_run_jobnet_summary_table as JR
        where JR.status=2
        UNION
        SELECT JR2.*
        FROM
        ja_2_ran_jobnet_summary_table as JR2
        where JR2.status=2
        ORDER BY start_time,inner_jobnet_id
        ";
        $this->db->query($query);

        return $this->db->resultSet();
    }

    /**
     * It retrieves the running jobnet summary for all other users.
     *
     * @param   array $usernames array of user which are in same group
     * @return  string
     * @since   Method available since version 6.1.0
     */
    public function getJobnetRunningSummaryForAll(array $usernames)
    {
        $placeholders = "'" . implode("','", $usernames) . "'";
        
        $sql1 = "
        SELECT JR.*
        FROM
        ja_2_run_jobnet_summary_table as JR
        where 
            JR.status=2 
            AND JR.public_flag = 1 
        UNION 
        SELECT JR2.*
        FROM
        ja_2_ran_jobnet_summary_table as JR2
        where 
            JR2.status=2 
            AND JR2.public_flag = 1
        ";

        $sql2 = "
        SELECT JR.*
        FROM
        ja_2_run_jobnet_summary_table as JR
        where 
            JR.status=2 
            AND JR.public_flag = 0 
            AND JR.user_name IN ($placeholders) 
        UNION 
        SELECT JR2.*
        FROM
        ja_2_ran_jobnet_summary_table as JR2
        where 
            JR2.status=2 
            AND JR2.public_flag = 0 
            AND JR2.user_name IN ($placeholders) 
        ";

        $mainSql = "
        SELECT JRAll.*
        FROM
        (
            ($sql1) 
            UNION
            ($sql2)
        ) AS JRAll 
        ORDER BY JRAll.start_time, JRAll.inner_jobnet_id";

        $this->db->query($mainSql);

        return $this->db->resultSet();
    }

    /**
     * It retrieves the jobnet summary data for the user who is not belong to user group.
     *
     * @param   string $fromTime (YmdHi)
     * @param   string $toTime (YmdHi)
     * @param   string $startFromTime (YmdHis)
     * @param   string $startToTime (YmdHis)
     * @param   array $usernames array of user which are in not belonging group
     * @return  array
     * @since   Method available since version 6.1.0
     */
    public function getJobnetSummaryForNotBelongGroup($fromTime, $toTime, $startFromTime, $startToTime,array $usernames)
    {
        $placeholders = "'" . implode("','", $usernames) . "'";

        $sql1= "
            SELECT JR.* 
            FROM 
            ja_2_run_jobnet_summary_table AS JR 
            WHERE
                (
                    (JR.scheduled_time BETWEEN $fromTime AND $toTime) OR 
                    (JR.start_time BETWEEN $startFromTime AND $startToTime) OR 
                    (JR.scheduled_time = 0 AND JR.start_time BETWEEN $startFromTime AND $startToTime) OR 
                    (JR.scheduled_time = 0 AND JR.start_time = 0 AND multiple_start_up = 2)
                )
            AND JR.public_flag = 1 
            AND JR.delete_flag = 0 
            UNION 
            SELECT JR2.* 
            FROM 
            ja_2_ran_jobnet_summary_table AS JR2 
            WHERE
                (
                    (JR2.scheduled_time BETWEEN $fromTime AND $toTime) OR 
                    (JR2.start_time BETWEEN $startFromTime AND $startToTime) OR 
                    (JR2.scheduled_time = 0 AND JR2.start_time BETWEEN $startFromTime AND $startToTime) OR 
                    (JR2.scheduled_time = 0 AND JR2.start_time = 0 AND multiple_start_up = 2)
                )
            AND JR2.public_flag = 1 
            AND JR2.delete_flag = 0 
            ";

        $sql2 = "
            SELECT JR.* 
            FROM 
            ja_2_run_jobnet_summary_table AS JR 
            WHERE
                (
                    (JR.scheduled_time BETWEEN $fromTime AND $toTime) OR 
                    (JR.start_time BETWEEN $startFromTime AND $startToTime) OR 
                    (JR.scheduled_time = 0 AND JR.start_time BETWEEN $startFromTime AND $startToTime) OR 
                    (JR.scheduled_time = 0 AND JR.start_time = 0 AND multiple_start_up = 2)
                )
            AND JR.public_flag = 1 
            AND JR.delete_flag = 0 
            AND JR.user_name IN ($placeholders) 
            UNION 
            SELECT JR2.* 
            FROM 
            ja_2_ran_jobnet_summary_table AS JR2 
            WHERE
                (
                    (JR2.scheduled_time BETWEEN $fromTime AND $toTime) OR 
                    (JR2.start_time BETWEEN $startFromTime AND $startToTime) OR 
                    (JR2.scheduled_time = 0 AND JR2.start_time BETWEEN $startFromTime AND $startToTime) OR 
                    (JR2.scheduled_time = 0 AND JR2.start_time = 0 AND multiple_start_up = 2)
                )
            AND JR2.public_flag = 1 
            AND JR2.delete_flag = 0 
            AND JR2.user_name IN ($placeholders) 
        ";

        $mainSql = "
            SELECT JRAll.*
            FROM
                (
                    ($sql1) 
                    UNION
                    ($sql2) 
                ) AS JRAll
            ORDER BY JRAll.scheduled_time, JRAll.start_time, JRAll.inner_jobnet_id
        ";
        $this->db->query($sql1);

        return $this->db->resultSet();
    }

    /**
     * It updates the run jobnet summary data.
     *
     * @param   array $data
     * @param   string $where
     * @return  bool
     * @since   Method available since version 6.1.0
     */
    public function updateRunJobnetSummary($data, $where)
    {
        $this->db->query($this->dbUtilModel->build_sql_update("ja_2_run_jobnet_summary_table", $data, $where));

        if ($this->db->execute()) {
            return true;
        } else {
            return false;
        }
    }
}
