#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define INITWKR 25

typedef struct {
    char *name;             /* worker name      */
    int *time;              /* time array (min) */  /* optional     */
    unsigned entries;       /* entris in time   */
    unsigned size;          /* allocated size   */  /* realloc test */
    int total;              /* total time (min) */
} worker;

int main () {

    char *name = NULL;      /* name input       */
    int tio = 0;            /* time input       */
    int idx = 0;            /* workers index    */
    int idxmax = 0;         /* index max time   */
    int tdx = 0;            /* time index       */
    int tmax = 0;           /* max worker time  */
    char exist = 0;         /* wkr exists flag  */

    /* create INITWKR pointers to struct (initialize NULL) */
    worker **wkrs = calloc (INITWKR, sizeof (*wkrs));
    if (!wkrs) {
        fprintf (stderr, "error: virtual memory exhausted.\n");
        return 1;
    }

    printf ("\nPunch the clock, enter name & minutes worked ([enter] alone to end)\n");

    /* input loop, read name and minutes work for each shift */
    while (printf ("\n  name: ") && scanf ("%m[^\n]%*c", &name) >= 1 &&
            printf ("  time: ") && scanf ("%d%*c", &tio) >= 1 )
    {
        idx = 0;            /* reset loop variables     */
        exist = 0;

        while (wkrs[idx])   /* check each filled worker */
        {
            /* check if already has struct  */
            if (strcmp (wkrs[idx]->name, name) == 0) {
                exist = 1;
                break;
            }
            idx++;          /* points to next avail pointer */
        }
        /* if (idx >= INITWKR - 1) reallocate poiner array  */

        if (!exist) {
            /* add new worker / verify each allocation */
            if (!(wkrs[idx] = malloc (sizeof (**wkrs)))) {
                fprintf (stderr, "error: virtual memory exhausted.\n");
                return 1;
            }
            if (!(wkrs[idx]-> name = strdup (name))) {
                fprintf (stderr, "error: virtual memory exhausted.\n");
                return 1;
            }
             if (!(wkrs[idx]-> time = calloc (INITWKR, sizeof (int)))) {
                fprintf (stderr, "error: virtual memory exhausted.\n");
                return 1;
            }
            wkrs[idx]-> entries = 0;
            wkrs[idx]-> size = INITWKR;
            wkrs[idx]-> total = 0;
        }

        /* add time to worker */
        tdx = 0;
        while ((wkrs[idx]-> time)[tdx])
            tdx++;
        /* if (tdx >= wkrs[idx]-> size - 1)
               reallocate wkrs[idx]-> time, increment size */
        (wkrs[idx]-> time)[tdx] = tio;
        wkrs[idx]-> entries++;
        wkrs[idx]-> total += tio;
        if (wkrs[idx]-> total > tmax) {
            tmax = wkrs[idx]-> total;
            idxmax = idx;
        }

        if (name) free (name);  /* free memory allocate by scanf    */
        name = NULL;
    }

    printf ("\nWorker Time Summary:\n\n");

    idx = 0;
    while (wkrs[idx]) {     /* output worker name/time & max    */
        if (idx == idxmax)
            printf ("  Worker[%2d] : %-24s   time: %d  (max time)\n", idx, wkrs[idx]->name, wkrs[idx]->total);
        else
            printf ("  Worker[%2d] : %-24s   time: %d\n", idx, wkrs[idx]->name, wkrs[idx]->total);
        idx++;
    }
    printf ("\n");

    idx = 0;
    while (wkrs[idx]) {     /* free dynamically allocated mem   */
        if (wkrs[idx]->name) free (wkrs[idx]->name);
        if (wkrs[idx]->time) free (wkrs[idx]->time);
        if (wkrs[idx]) free (wkrs[idx++]);
    }
    free (wkrs);

    return 0;
}

// **example:**
//
//     $ ./bin/workers
//
//     Punch the clock, enter name & minutes worked ([enter] alone to end)
//
//       name: JD Clark
//       time: 38
//
//       name: Mike Wu
//       time: 34
//
//       name: JD Clark
//       time: 39
//
//       name: Mike Wu
//       time: 53
//
//       name: JD Clark
//       time: 64
//
//       name: Tim Taylor
//       time: 55
//
//       name:
//
//     Worker Time Summary:
//
//       Worker[ 0] : JD Clark                   time: 141  (max time)
//       Worker[ 1] : Mike Wu                    time: 87
//       Worker[ 2] : Tim Taylor                 time: 55