<?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\Model;
use App\Utils\Constants;

/**
 * This model is used to manage the index.
 *
 * @version    6.1.0
 * @since      Class available since version 6.1.0
 */
class IndexModel extends Model
{
    /**
     * It retrieves the next object id and increase 1.
     *
     * @param   int    $id      object id 
     * @return  string $nextId  last object id
     * @since   Method available since version 6.1.0
     */
    public function getNextIdAndIncrease($id)
    {
        $nextId = $this->getNextID($id);
        if (!$this->increateNextID($id, 1)) {
            $nextId = false;
        }
        return $nextId;
    }
    /**
     * It retrieves the next new copy object id.
     *
     * @param   int    $id      object id 
     * @return  string $nextId  new copy object id
     * @since   Method available since version 7.0
     */
    public function getNextNewObjectId($id,$type)
    {
        $tmp_id = $id . '%';
        if($type == Constants::COUNT_ID_JOBNET){
            $this->db->query("SELECT COUNT(DISTINCT jobnet_id) as count FROM ja_2_jobnet_control_table WHERE jobnet_id LIKE :id");
        }else if($type == Constants::COUNT_ID_CALENDAR){
            $this->db->query("SELECT COUNT(DISTINCT calendar_id) as count FROM ja_2_calendar_control_table WHERE calendar_id LIKE :id");
        }else if($type == Constants::COUNT_ID_SCHEDULE){
            $this->db->query("SELECT COUNT(DISTINCT schedule_id) as count FROM ja_2_schedule_control_table WHERE schedule_id LIKE :id");
        }else if($type == Constants::COUNT_ID_FILTER){
            $this->db->query("SELECT COUNT(DISTINCT filter_id) as count FROM ja_2_filter_control_table WHERE filter_id LIKE :id");
        }
        $this->db->bind(':id', $tmp_id);
        $result = $this->db->single();
        $result_cnt = $result->{'count'};
        return $result_cnt > 1 ? (string)$result_cnt :  '1';
    }

    /**
     * It retrieves the next object id.
     *
     * @param   int $id  object id count
     * @return  string last object id
     * @since   Method available since version 6.1.0
     */
    public function getNextID($id)
    {
        $this->db->query("SELECT nextid FROM ja_2_index_table WHERE count_id = '$id' for update");
        if($id == Constants::COUNT_INNER_JOBNET_ID){
            $result = $this->db->single();
            if($this->checkIdDuplicate($result->nextid)){
                $this->increateNextID($id);
                return $this->getNextID($id);
            }
            // return $result->nextid;
        }else{
        $result = $this->db->single();
        }
        return $result;
    }

     /**
     * It check the next object id.
     *
     * @param   int $id  object id count
     * @return  string last object id
     * @since   Method available since version 6.1.1
     */
    public function checkIdDuplicate($id)
    {
        $this->db->query("SELECT inner_jobnet_id FROM ja_2_run_jobnet_table WHERE inner_jobnet_id = '$id'");
        return $this->db->single();
    }

    /**
     * It increase the object id after retrieve next id
     *
     * @param   int $id    object id count
     * @param   int $plus  
     * @return  bool could be true if increase process success, could be false if fail
     * @since   Method available since version 6.1.0
     */
    public function increateNextID($id, $plus = null)
    {
        if ($plus == null) {
            $plus = 1;
        }
        $this->db->query('UPDATE ja_2_index_table SET nextid = nextid + :plus WHERE count_id = :id');

        $this->db->bind(':id', $id);
        $this->db->bind(':plus', $plus);

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