/*
 * 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.
 */

#include "fcgid_spawn_ctl.h"
#include "fcgid_conf.h"
#define REGISTER_LIFE 1
#define REGISTER_DEATH 2

struct fcgid_stat_node {
    apr_ino_t inode;
    dev_t deviceid;
    uid_t uid;
    gid_t gid;
    apr_size_t share_grp_id;
    char *virtualhost;
    int score;
    int process_counter;
    apr_time_t last_stat_time;
    struct fcgid_stat_node *next;
};

static apr_pool_t *g_stat_pool = NULL;
static struct fcgid_stat_node *g_stat_list_header = NULL;
static int g_time_score;
static int g_termination_score;
static int g_spawn_score;
static int g_score_uplimit;
static int g_max_process;
static int g_total_process;
static int g_max_class_process;
static int g_min_class_process;

static void
register_life_death(server_rec * main_server,
                    fcgid_procnode * procnode, int life_or_death)
{
    struct fcgid_stat_node *previous_node, *current_node;

    if (!g_stat_pool || !procnode)
        abort();

    /* Can I find the node base on inode, device id and share group id? */
    previous_node = g_stat_list_header;
    for (current_node = previous_node;
         current_node != NULL; current_node = current_node->next) {
        if (current_node->inode == procnode->inode
            && current_node->deviceid == procnode->deviceid
            && current_node->share_grp_id == procnode->share_grp_id
            && current_node->virtualhost == procnode->virtualhost
            && current_node->uid == procnode->uid
            && current_node->gid == procnode->gid)
            break;
        previous_node = current_node;
    }

    if (current_node) {
        /* Found the node */
        apr_time_t now = apr_time_now();

        /* Increase the score first */
        if (life_or_death == REGISTER_LIFE) {
            current_node->score += g_spawn_score;
            current_node->process_counter++;
        } else {
            current_node->score += g_termination_score;
            current_node->process_counter--;
        }

        /* Decrease the score base on the time passing */
        current_node->score -= g_time_score * (int) (apr_time_sec(now)
                                                     -
                                                     apr_time_sec
                                                     (current_node->
                                                      last_stat_time));

        /* Make score reasonable */
        if (current_node->score < 0)
            current_node->score = 0;

        current_node->last_stat_time = now;
    } else {
        /* I can't find it, create one */
        current_node = apr_pcalloc(g_stat_pool, sizeof(*current_node));
        if (!current_node)
            return;
        current_node->deviceid = procnode->deviceid;
        current_node->inode = procnode->inode;
        current_node->share_grp_id = procnode->share_grp_id;
        current_node->virtualhost = procnode->virtualhost;
        current_node->uid = procnode->uid;
        current_node->gid = procnode->gid;
        current_node->last_stat_time = apr_time_now();
        current_node->score = 0;
        current_node->process_counter = 1;
        current_node->next = NULL;

        /* append it to stat list for next search */
        if (!previous_node)
            g_stat_list_header = current_node;
        else
            previous_node->next = current_node;
    }
}

void spawn_control_init(server_rec * main_server, apr_pool_t * configpool)
{
    apr_status_t rv;

    if ((rv = apr_pool_create(&g_stat_pool, configpool)) != APR_SUCCESS) {
        /* Fatal error */
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
                     "mod_fcgid: can't create stat pool");
        exit(1);
    }

    /* Initialize the variables from configuration */
    g_time_score = get_time_score(main_server);
    g_termination_score = get_termination_score(main_server);
    g_spawn_score = get_spawn_score(main_server);
    g_score_uplimit = get_spawnscore_uplimit(main_server);
    g_max_process = get_max_process(main_server);
    g_max_class_process = get_max_class_process(main_server);
    g_min_class_process = get_min_class_process(main_server);
}

void
register_termination(server_rec * main_server, fcgid_procnode * procnode)
{
    register_life_death(main_server, procnode, REGISTER_DEATH);
    g_total_process--;
}

void register_spawn(server_rec * main_server, fcgid_procnode * procnode)
{
    register_life_death(main_server, procnode, REGISTER_LIFE);
    g_total_process++;
}

/* 
    Spawn control is base on such strategy:
    1. Increate score if application is terminated
    2. Increate score if application is spawned
    3. Decrease score each second while score is positive
    4. Negative spawn request if score is higher than up limit
    5. Negative spawn request if total process count higher than up limit
    6. Negative spawn request if process count of this class higher than up limit
*/
int is_spawn_allowed(server_rec * main_server, fcgid_command * command)
{
    struct fcgid_stat_node *current_node;

    if (!command || !g_stat_pool)
        return 1;

    /* Can I find the node base on inode, device id and share group id? */
    for (current_node = g_stat_list_header;
         current_node != NULL; current_node = current_node->next) {
        if (current_node->inode == command->inode
            && current_node->deviceid == command->deviceid
            && current_node->share_grp_id == command->share_grp_id
            && current_node->virtualhost == command->virtualhost
            && current_node->uid == command->uid
            && current_node->gid == command->gid)
            break;
    }

    if (!current_node)
        return 1;
    else {
        apr_time_t now = apr_time_now();

        current_node->score -= g_time_score * (int) (apr_time_sec(now)
                                                     -
                                                     apr_time_sec
                                                     (current_node->
                                                      last_stat_time));
        current_node->last_stat_time = now;
        if (current_node->score < 0)
            current_node->score = 0;

        /* Score is higher than up limit? */
        if (current_node->score >= g_score_uplimit) {
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, main_server,
                         "mod_fcgid: %s spawn score %d >= %d, skip the spawn request",
                         command->cgipath, current_node->score,
                         g_score_uplimit);
            return 0;
        }

        /* Total process count higher than up limit? */
        if (g_total_process >= g_max_process) {
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
                         "mod_fcgid: %s total process count %d >= %d, skip the spawn request",
                         command->cgipath, g_total_process, g_max_process);
            return 0;
        }

        /* 
           Process count of this class higher than up limit?
         */
        /* I need max class proccess count */
        if (current_node->process_counter >= g_max_class_process) {
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
                         "mod_fcgid: too much %s process(current:%d, max:%d), skip the spawn request",
                         command->cgipath, current_node->process_counter,
                         g_max_class_process);
            return 0;
        }

        return 1;
    }
}

int is_kill_allowed(fcgid_procnode * procnode)
{
    struct fcgid_stat_node *previous_node, *current_node;

    if (!g_stat_pool || !procnode)
        return 0;

    /* Can I find the node base on inode, device id and share group id? */
    previous_node = g_stat_list_header;
    for (current_node = previous_node;
         current_node != NULL; current_node = current_node->next) {
        if (current_node->inode == procnode->inode
            && current_node->deviceid == procnode->deviceid
            && current_node->share_grp_id == procnode->share_grp_id
            && current_node->virtualhost == procnode->virtualhost
            && current_node->uid == procnode->uid
            && current_node->gid == procnode->gid)
            break;
        previous_node = current_node;
    }

    if (current_node) {
        /* Found the node */
        if (current_node->process_counter <= g_min_class_process)
            return 0;
    }

    return 1;
}
