/*
 * Copyright (c) 1999 Theo de Raadt.  All rights reserved.
 * Copyright (c) 1999 Aaron Campbell.  All rights reserved.
 *
 * 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
 */

/*
 * Parts from:
 *
 * Copyright (c) 1983, 1990, 1992, 1993, 1995
 *	The Regents of the University of California.  All rights reserved.
 *
 * 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. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 "includes.h"
RCSID("$OpenBSD: progressmeter.c,v 1.2 2003/01/12 16:57:02 markus Exp $");

#include <libgen.h>

#include "atomicio.h"
#include "progressmeter.h"

/* Number of seconds before xfer considered "stalled". */
#define STALLTIME	5
/* alarm() interval for updating progress meter. */
#define PROGRESSTIME	1

/* Signal handler used for updating the progress meter. */
static void update_progress_meter(int);

/* Returns non-zero if we are the foreground process. */
static int foregroundproc(void);

/* Returns width of the terminal (for progress meter calculations). */
static int get_tty_width(void);

/* Visual statistics about files as they are transferred. */
static void draw_progress_meter(void);

/* Time a transfer started. */
static struct timeval start;

/* Number of bytes of current file transferred so far. */
static volatile off_t *statbytes;

/* Total size of current file. */
static off_t totalbytes;

/* Name of current file being transferred. */
static char *curfile;

/* Time of last update. */
static struct timeval lastupdate;

/* Size at the time of the last update. */
static off_t lastsize;

void
start_progress_meter(char *file, off_t filesize, off_t *counter)
{
	if ((curfile = basename(file)) == NULL)
		curfile = file;

	totalbytes = filesize;
	statbytes = counter;
	(void) gettimeofday(&start, (struct timezone *) 0);
	lastupdate = start;
	lastsize = 0;

	draw_progress_meter();
	signal(SIGALRM, update_progress_meter);
	alarm(PROGRESSTIME);
}

void
stop_progress_meter()
{
	alarm(0);
	draw_progress_meter();
	atomicio(write, fileno(stdout), "\n", 1);
}

static void
update_progress_meter(int ignore)
{
	int save_errno = errno;

	draw_progress_meter();
	signal(SIGALRM, update_progress_meter);
	alarm(PROGRESSTIME);
	errno = save_errno;
}

static int
foregroundproc(void)
{
	static pid_t pgrp = -1;
	int ctty_pgrp;

	if (pgrp == -1)
		pgrp = getpgrp();

	return ((ioctl(STDOUT_FILENO, TIOCGPGRP, &ctty_pgrp) != -1 &&
		 ctty_pgrp == pgrp));
}

static void
draw_progress_meter()
{
	static const char spaces[] = "                          "
	    "                                                   "
	    "                                                   "
	    "                                                   "
	    "                                                   "
	    "                                                   ";
	static const char prefixes[] = " KMGTP";
	struct timeval now, td, wait;
	off_t cursize, abbrevsize, bytespersec;
	double elapsed;
	int ratio, remaining, i, ai, bi, nspaces;
	char buf[512];

	if (foregroundproc() == 0)
		return;

	(void) gettimeofday(&now, (struct timezone *) 0);
	cursize = *statbytes;
	if (totalbytes != 0) {
		ratio = 100.0 * cursize / totalbytes;
		ratio = MAX(ratio, 0);
		ratio = MIN(ratio, 100);
	} else
		ratio = 100;

	abbrevsize = cursize;
	for (ai = 0; abbrevsize >= 10000 && ai < sizeof(prefixes); ai++)
		abbrevsize >>= 10;

	timersub(&now, &lastupdate, &wait);
	if (cursize > lastsize) {
		lastupdate = now;
		lastsize = cursize;
		wait.tv_sec = 0;
	}
	timersub(&now, &start, &td);
	elapsed = td.tv_sec + (td.tv_usec / 1000000.0);

	bytespersec = 0;
	if (cursize > 0) {
		bytespersec = cursize;
		if (elapsed > 0.0)
			bytespersec /= elapsed;
	}
	for (bi = 1; bytespersec >= 1024000 && bi < sizeof(prefixes); bi++)
		bytespersec >>= 10;

    	nspaces = MIN(get_tty_width() - 79, sizeof(spaces) - 1);

	snprintf(buf, sizeof(buf),
	    "\r%-45.45s%.*s%3d%% %4lld%c%c %3lld.%01d%cB/s",
	    curfile,
	    nspaces,
	    spaces,
	    ratio,
	    (long long)abbrevsize,
	    prefixes[ai],
	    ai == 0 ? ' ' : 'B',
	    (long long)(bytespersec / 1024),
	    (int)((bytespersec % 1024) * 10 / 1024),
	    prefixes[bi]
	);

	if (cursize <= 0 || elapsed <= 0.0 || cursize > totalbytes) {
		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
		    "   --:-- ETA");
	} else if (wait.tv_sec >= STALLTIME) {
		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
		    " - stalled -");
	} else {
		if (cursize != totalbytes)
			remaining = (int)(totalbytes / (cursize / elapsed) -
			    elapsed);
		else
			remaining = elapsed;

		i = remaining / 3600;
		if (i)
			snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
			    "%2d:", i);
		else
			snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
			    "   ");
		i = remaining % 3600;
		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
		    "%02d:%02d%s", i / 60, i % 60,
		    (cursize != totalbytes) ? " ETA" : "    ");
	}
	atomicio(write, fileno(stdout), buf, strlen(buf));
}

static int
get_tty_width(void)
{
	struct winsize winsize;

	if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1)
		return (winsize.ws_col ? winsize.ws_col : 80);
	else
		return (80);
}
