/*
 zip_progress.c -- progress reporting
 Copyright (C) 2017 Dieter Baron and Thomas Klausner

 This file is part of libzip, a library to manipulate ZIP archives.
 The authors can be contacted at <libzip@nih.at>

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
 notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
 notice, this list of conditions and the following disclaimer in
 the documentation and/or other materials provided with the
 distribution.
 3. The names of the authors may not be used to endorse or promote
 products derived from this software without specific prior
 written permission.

 THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


#include <stdlib.h>


#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"

struct zip_progress {
    zip_t *za;
    zip_progress_callback callback;
    void (*ud_free)(void *);

    void *ud;

    double precision;

    /* state */
    double last_update;  /* last value callback function was called with */

    double start;        /* start of sub-progress section */
    double end;          /* end of sub-progress section */
};


void
_zip_progress_end(zip_progress_t *progress) {
    _zip_progress_update(progress, 1.0);
}


void
_zip_progress_free(zip_progress_t *progress) {
    if (progress == NULL) {
        return;
    }

    if (progress->ud_free) {
        progress->ud_free(progress->ud);
    }

    free(progress);
}


zip_progress_t *
_zip_progress_new(zip_t *za, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud) {
    zip_progress_t *progress = (zip_progress_t *)malloc(sizeof(*progress));

    if (progress == NULL) {
        zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
        return NULL;
    }

    progress->za = za;
    progress->callback = callback;
    progress->ud_free = ud_free;
    progress->ud = ud;
    progress->precision = precision;

    return progress;
}


void
_zip_progress_start(zip_progress_t *progress) {
    if (progress == NULL) {
        return;
    }

    progress->last_update = 0.0;
    progress->callback(progress->za, 0.0, progress->ud);
}


void
_zip_progress_subrange(zip_progress_t *progress, double start, double end) {
    if (progress == NULL) {
        return;
    }

    progress->start = start;
    progress->end = end;

    _zip_progress_update(progress, 0.0);
}

void
_zip_progress_update(zip_progress_t *progress, double sub_current) {
    double current;

    if (progress == NULL) {
        return;
    }

    current = ZIP_MIN(ZIP_MAX(sub_current, 0.0), 1.0) * (progress->end - progress->start) + progress->start;

    if (current - progress->last_update > progress->precision) {
        progress->callback(progress->za, current, progress->ud);
        progress->last_update = current;
    }
}


ZIP_EXTERN int
zip_register_progress_callback_with_state(zip_t *za, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud) {
    zip_progress_t *progress = NULL;

    if (callback != NULL) {
        if ((progress = _zip_progress_new(za, precision, callback, ud_free, ud)) == NULL) {
            return -1;
        }
    }

    _zip_progress_free(za->progress);
    za->progress = progress;

    return 0;
}


struct legacy_ud {
    zip_progress_callback_t callback;
};


static void
_zip_legacy_progress_callback(zip_t *za, double progress, void *vud) {
    struct legacy_ud *ud = (struct legacy_ud *)vud;

    ud->callback(progress);
}

ZIP_EXTERN void
zip_register_progress_callback(zip_t *za, zip_progress_callback_t progress_callback)
{
    struct legacy_ud *ud;
    
    if (progress_callback == NULL) {
        zip_register_progress_callback_with_state(za, 0, NULL, NULL, NULL);
    }

    if ((ud = (struct legacy_ud *)malloc(sizeof(*ud))) == NULL) {
        return;
    }

    ud->callback = progress_callback;

    if (zip_register_progress_callback_with_state(za, 0.001, _zip_legacy_progress_callback, free, ud) < 0) {
        free(ud);
    }
}
