/*
 * DisMan Schedule MIB:
 *     Core implementation of the schedule handling behaviour
 */

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "disman/schedule/schedCore.h"
#include "utilities/iquery.h"

netsnmp_tdata *schedule_table;

    /*
     * Initialize the container for the schedule table,
     * regardless of which initialisation routine is called first.
     */
void
init_schedule_container(void)
{
    DEBUGMSGTL(("disman:schedule:init", "init schedule container\n"));
    if (!schedule_table) {
        schedule_table = netsnmp_tdata_create_table("schedTable", 0);
        DEBUGMSGTL(("disman:schedule:init",
                        "create schedule container(%p)\n", schedule_table));
    }
}

/** Initializes the schedCore module */
void
init_schedCore(void)
{
    /*
     * Create a table structure for the schedule table
     * This will typically be registered by the schedTable module
     */
    DEBUGMSGTL(("disman:schedule:init", "Initializing core module\n"));
    init_schedule_container();
}


/*
 * Callback to invoke a scheduled action
 */
static void
_sched_callback( unsigned int reg, void *magic )
{
    struct schedTable_entry *entry = (struct schedTable_entry *)magic;
    int ret;
    netsnmp_variable_list assign;

    if ( !entry ) {
        DEBUGMSGTL(("disman:schedule:callback", "missing entry\n"));
        return;
    }
    entry->schedLastRun = time(NULL);
    entry->schedTriggers++;

    DEBUGMSGTL(( "disman:schedule:callback", "assignment "));
    DEBUGMSGOID(("disman:schedule:callback", entry->schedVariable,
                                             entry->schedVariable_len));
    DEBUGMSG((   "disman:schedule:callback", " = %ld\n", entry->schedValue));

    memset(&assign, 0, sizeof(netsnmp_variable_list));
    snmp_set_var_objid(&assign, entry->schedVariable, entry->schedVariable_len);
    snmp_set_var_typed_value(&assign, ASN_INTEGER,
                                     (u_char *)&entry->schedValue,
                                         sizeof(entry->schedValue));

    ret = netsnmp_query_set( &assign, entry->session );
    if ( ret != SNMP_ERR_NOERROR ) {
        DEBUGMSGTL(( "disman:schedule:callback",
                     "assignment failed (%d)\n", ret));
        entry->schedFailures++;
        entry->schedLastFailure = ret;
        time ( &entry->schedLastFailed );
    }

    sched_nextTime( entry );
}


    /*
     * Internal utility routines to help interpret
     *  calendar-based schedule bit strings
     */
static char _masks[] = { /* 0xff, */ 0x7f, 0x3f, 0x1f,
                         0x0f, 0x07, 0x03, 0x01, 0x00 };
static char _bits[]  = { 0x80, 0x40, 0x20, 0x10,
                         0x08, 0x04, 0x02, 0x01 };

/*
 * Are any of the bits set?
 */
static int
_bit_allClear( char *pattern, int len ) {
    int i;

    for (i=0; i<len; i++) {
        if ( pattern[i] != 0 )
            return 0;    /* At least one bit set */
    }
    return 1;  /* All bits clear */ 
}

/*
 * Is a particular bit set?
 */
static int
_bit_set( char *pattern, int bit ) {
    int major, minor;

    major = bit/8;
    minor = bit%8;
    if ( pattern[major] & _bits[minor] ) {
        return 1; /* Specified bit is set */
    }
    return 0;     /* Bit not set */
}

/*
 * What is the next bit set?
 *   (after a specified point)
 */
static int
_bit_next( char *pattern, int current, size_t len ) {
    char buf[ 8 ];
    int major, minor, i, j;

        /* Make a working copy of the bit pattern */
    memset( buf, 0, 8 );
    memcpy( buf, pattern, len );

        /*
         * If we're looking for the first bit after some point,
         * then clear all earlier bits from the working copy.
         */
    if ( current > -1 ) {
        major = current/8;
        minor = current%8;
        for ( i=0; i<major; i++ )
            buf[i]=0;
        buf[major] &= _masks[minor];
    }

        /*
         * Look for the first bit that's set
         */
    for ( i=0; i<len; i++ ) {
        if ( buf[i] != 0 ) {
            major = i*8;
            for ( j=0; j<8; j++ ) {
                if ( buf[i] & _bits[j] ) {
                    return major+j;
                }
            }
        }
    }
    return -1;     /* No next bit */
}


static int _daysPerMonth[] = { 31, 28, 31, 30,
                               31, 30, 31, 31,
                               30, 31, 30, 31, 29 };

static char _truncate[] = { 0xfe, 0xf0, 0xfe, 0xfc,
                            0xfe, 0xfc, 0xfe, 0xfe,
                            0xfc, 0xfe, 0xfc, 0xfe, 0xf8 };

/*
 * What is the next day with a relevant bit set?
 *
 * Merge the forward and reverse day bits into a single
 *   pattern relevant for this particular month,
 *   and apply the standard _bit_next() call.
 * Then check this result against the day of the week bits.
 */
static int
_bit_next_day( char *day_pattern, char weekday_pattern,
               int day, int month, int year ) {
    char buf[4];
    union {
        char buf2[4];
        int int_val;
    } rev;
    int next_day, i;
    struct tm tm_val;

        /* Make a working copy of the forward day bits ... */
    memset( buf,  0, 4 );
    memcpy( buf,  day_pattern, 4 );

        /* ... and another (right-aligned) of the reverse day bits */
    memset( rev.buf2, 0, 4 );
    memcpy( rev.buf2, day_pattern+4, 4 );
    rev.int_val >>= 2;
    if ( buf[3] & 0x01 )
        rev.buf2[0] |= 0x40;
    if ( month == 3 || month == 5 ||
         month == 8 || month == 10 )
        rev.int_val >>= 1;  /* April, June, September, November */
    if ( month == 1 )
        rev.int_val >>= 3;  /* February */
    if ( month == 12 )
        rev.int_val >>= 2;  /* February (leap year) */

        /* Combine the two bit patterns, and truncate to the month end */
    for ( i=0; i<4; i++ ) {
        if ( rev.buf2[i] & 0x80 ) buf[3-i] |= 0x01;
        if ( rev.buf2[i] & 0x40 ) buf[3-i] |= 0x02;
        if ( rev.buf2[i] & 0x20 ) buf[3-i] |= 0x04;
        if ( rev.buf2[i] & 0x10 ) buf[3-i] |= 0x08;
        if ( rev.buf2[i] & 0x08 ) buf[3-i] |= 0x10;
        if ( rev.buf2[i] & 0x04 ) buf[3-i] |= 0x20;
        if ( rev.buf2[i] & 0x02 ) buf[3-i] |= 0x40;
        if ( rev.buf2[i] & 0x01 ) buf[3-i] |= 0x80;
    }

    buf[3] &= _truncate[ month ];

    next_day = day-1;  /* tm_day is 1-based, not 0-based */
    do {
        next_day = _bit_next( buf, next_day, 4 );
        if ( next_day < 0 )
            return -1;

            /*
             * Calculate the day of the week, and
             * check this against the weekday pattern
             */
        memset( &tm_val,  0, sizeof(struct tm));
        tm_val.tm_mday = next_day+1;
        tm_val.tm_mon  = month;
        tm_val.tm_year = year;
        mktime( &tm_val );
    } while ( !_bit_set( &weekday_pattern, tm_val.tm_wday ));
    return next_day+1; /* Convert back to 1-based list */
}


/*
 * determine the time for the next scheduled action of a given entry
 */
void
sched_nextTime( struct schedTable_entry *entry )
{
    time_t now;
    struct tm now_tm, next_tm;
    int rev_day, mon;

    time( &now );

    if ( !entry ) {
        DEBUGMSGTL(("disman:schedule:time", "missing entry\n"));
        return;
    }

    if ( entry->schedCallbackID )
        snmp_alarm_unregister( entry->schedCallbackID );

    if (!(entry->flags & SCHEDULE_FLAG_ENABLED) ||
        !(entry->flags & SCHEDULE_FLAG_ACTIVE))  {
        DEBUGMSGTL(("disman:schedule:time", "inactive entry\n"));
        return;
    }

    switch ( entry->schedType ) {
    case SCHED_TYPE_PERIODIC:
        if ( !entry->schedInterval ) {
            DEBUGMSGTL(("disman:schedule:time", "periodic: no interval\n"));
            return;
        }
        if ( entry->schedLastRun ) {
             entry->schedNextRun = entry->schedLastRun +
                                   entry->schedInterval;
        } else {
             entry->schedNextRun = now + entry->schedInterval;
        }
        DEBUGMSGTL(("disman:schedule:time", "periodic: (%ld) %s",
                                  entry->schedNextRun,
                           ctime(&entry->schedNextRun)));
        break;

    case SCHED_TYPE_ONESHOT:
        if ( entry->schedLastRun ) {
            DEBUGMSGTL(("disman:schedule:time", "one-shot: expired (%ld) %s",
                                  entry->schedNextRun,
                           ctime(&entry->schedNextRun)));
            return;
        }
        /* Fallthrough */
        DEBUGMSGTL(("disman:schedule:time", "one-shot: fallthrough\n"));
    case SCHED_TYPE_CALENDAR:
        /*
         *  Check for complete time specification
         *  If any of the five fields have no bits set,
         *    the entry can't possibly match any time.
         */
        if ( _bit_allClear( entry->schedMinute, 8 ) ||
             _bit_allClear( entry->schedHour,   3 ) ||
             _bit_allClear( entry->schedDay,  4+4 ) ||
             _bit_allClear( entry->schedMonth,  2 ) ||
             _bit_allClear(&entry->schedWeekDay, 1 )) {
            DEBUGMSGTL(("disman:schedule:time", "calendar: incomplete spec\n"));
            return;
        }

        /*
         *  Calculate the next run time:
         *
         *  If the current Month, Day & Hour bits are set
         *    calculate the next specified minute
         *  If this fails (or the current Hour bit is not set)
         *    use the first specified minute,
         *    and calculate the next specified hour
         *  If this fails (or the current Day bit is not set)
         *    use the first specified minute and hour
         *    and calculate the next specified day (in this month)
         *  If this fails (or the current Month bit is not set)
         *    use the first specified minute and hour
         *    calculate the next specified month, and
         *    the first specified day (in that month)
         */

        localtime_r( &now, &now_tm );
        localtime_r( &now, &next_tm );

        next_tm.tm_mon=-1;
        next_tm.tm_mday=-1;
        next_tm.tm_hour=-1;
        next_tm.tm_min=-1;
        next_tm.tm_sec=0;
        if ( _bit_set( entry->schedMonth, now_tm.tm_mon )) {
            next_tm.tm_mon = now_tm.tm_mon;
            rev_day = _daysPerMonth[ now_tm.tm_mon ] - now_tm.tm_mday;
            if ( _bit_set( &entry->schedWeekDay, now_tm.tm_wday ) &&
                (_bit_set( entry->schedDay, now_tm.tm_mday-1 ) ||
                 _bit_set( entry->schedDay, 31+rev_day ))) {
                next_tm.tm_mday = now_tm.tm_mday;

                if ( _bit_set( entry->schedHour, now_tm.tm_hour )) {
                    next_tm.tm_hour = now_tm.tm_hour;
                    /* XXX - Check Fall timechange */
                    next_tm.tm_min = _bit_next( entry->schedMinute,
                                                  now_tm.tm_min, 8 );
                } else {
                    next_tm.tm_min = -1;
                }
   
                if ( next_tm.tm_min == -1 ) {
                    next_tm.tm_min  = _bit_next( entry->schedMinute, -1, 8 );
                    next_tm.tm_hour = _bit_next( entry->schedHour,
                                                   now_tm.tm_hour, 3 );
                }
            } else {
                next_tm.tm_hour = -1;
            }

            if ( next_tm.tm_hour == -1 ) {
                next_tm.tm_min  = _bit_next( entry->schedMinute, -1, 8 );
                next_tm.tm_hour = _bit_next( entry->schedHour,   -1, 3 );
                    /* Handle leap years */
                mon = now_tm.tm_mon;
                if ( mon == 1 && (now_tm.tm_year%4 == 0) )
                    mon = 12;
                next_tm.tm_mday = _bit_next_day( entry->schedDay,
                                                 entry->schedWeekDay,
                                                 now_tm.tm_mday,
                                                 mon, now_tm.tm_year );
            }
        } else {
            next_tm.tm_min  = _bit_next( entry->schedMinute, -1, 2 );
            next_tm.tm_hour = _bit_next( entry->schedHour,   -1, 3 );
            next_tm.tm_mday = -1;
            next_tm.tm_mon  = now_tm.tm_mon;
        }

        while ( next_tm.tm_mday == -1 ) {
            next_tm.tm_mon  = _bit_next( entry->schedMonth,
                                          next_tm.tm_mon, 2 );
            if ( next_tm.tm_mon == -1 ) {
                next_tm.tm_year++;
                next_tm.tm_mon  = _bit_next( entry->schedMonth,
                                             -1, 2 );
            }
                /* Handle leap years */
            mon = next_tm.tm_mon;
            if ( mon == 1 && (next_tm.tm_year%4 == 0) )
                mon = 12;
            next_tm.tm_mday = _bit_next_day( entry->schedDay,
                                             entry->schedWeekDay,
                                             -1, mon, next_tm.tm_year );
            /* XXX - catch infinite loop */
        }

        /* XXX - Check for Spring timechange */

        /*
         * 'next_tm' now contains the time for the next scheduled run
         */
        entry->schedNextRun = mktime( &next_tm );
        DEBUGMSGTL(("disman:schedule:time", "calendar: (%ld) %s",
                                  entry->schedNextRun,
                           ctime(&entry->schedNextRun)));
        return;

    default:
        DEBUGMSGTL(("disman:schedule:time", "unknown type (%ld)\n",
                                             entry->schedType));
        return;
    }
    entry->schedCallbackID = snmp_alarm_register(
                                entry->schedNextRun - now,
                                0, _sched_callback, entry );
    return;
}

void
sched_nextRowTime( netsnmp_tdata_row *row )
{
    sched_nextTime((struct schedTable_entry *) row->data );
}

/*
 * create a new row in the table 
 */
netsnmp_tdata_row *
schedTable_createEntry(const char *schedOwner, const char *schedName)
{
    struct schedTable_entry *entry;
    netsnmp_tdata_row *row;

    DEBUGMSGTL(("disman:schedule:entry", "creating entry (%s, %s)\n",
                                          schedOwner, schedName));
    entry = SNMP_MALLOC_TYPEDEF(struct schedTable_entry);
    if (!entry)
        return NULL;

    row = netsnmp_tdata_create_row();
    if (!row) {
        SNMP_FREE(entry);
        return NULL;
    }
    row->data = entry;
    /*
     * Set the indexing for this entry, both in the row
     *  data structure, and in the table_data helper.
     */
    if (schedOwner) {
        memcpy(entry->schedOwner, schedOwner, strlen(schedOwner));
        netsnmp_tdata_row_add_index(row, ASN_OCTET_STR,
                           entry->schedOwner, strlen(schedOwner));
    }
    else
        netsnmp_tdata_row_add_index(row, ASN_OCTET_STR, "", 0 );

    memcpy(    entry->schedName,  schedName,  strlen(schedName));
    netsnmp_tdata_row_add_index(row, ASN_OCTET_STR,
                           entry->schedName,  strlen(schedName));
    /*
     * Set the (non-zero) default values in the row data structure.
     */
    entry->schedType         = SCHED_TYPE_PERIODIC;
    entry->schedVariable_len = 2;   /* .0.0 */

    netsnmp_tdata_add_row(schedule_table, row);
    return row;
}


/*
 * remove a row from the table 
 */
void
schedTable_removeEntry(netsnmp_tdata_row *row)
{
    struct schedTable_entry *entry;

    if (!row || !row->data) {
        DEBUGMSGTL(("disman:schedule:entry", "remove: missing entry\n"));
        return;                 /* Nothing to remove */
    }
    entry = (struct schedTable_entry *)
        netsnmp_tdata_remove_and_delete_row(schedule_table, row);
    if (entry) {
        DEBUGMSGTL(("disman:schedule:entry", "remove entry (%s, %s)\n",
                                     entry->schedOwner, entry->schedName));
        SNMP_FREE(entry);
    }
}
