<commit_before>/*
 * Copyright (C) 2017 <NAME> <<EMAIL>>
 *
 * SPDX-License-Identifier: LGPL-2.1+
 */

#define G_LOG_DOMAIN				"FuProgressBar"

#include "config.h"

#include <glib.h>
#include <glib/gi18n.h>

#include "fu-common.h"
#include "fu-progressbar.h"

static void fu_progressbar_finalize	 (GObject *obj);

struct _FuProgressbar
{
	GObject			 parent_instance;
	FwupdStatus		 status;
	gboolean		 spinner_count_up;	/* chars */
	guint			 spinner_idx;		/* chars */
	guint			 length_percentage;	/* chars */
	guint			 length_status;		/* chars */
	guint			 percentage;
	guint			 to_erase;		/* chars */
	guint			 timer_id;
	gint64			 last_animated;		/* monotonic */
	GTimer			*time_elapsed;
	gdouble			 last_estimate;
	gboolean		 interactive;
};

G_DEFINE_TYPE (FuProgressbar, fu_progressbar, G_TYPE_OBJECT)

static const gchar *
fu_progressbar_status_to_string (FwupdStatus status)
{
	switch (status) {
	case FWUPD_STATUS_IDLE:
		/* TRANSLATORS: daemon is inactive */
		return _("Idle…");
		break;
	case FWUPD_STATUS_DECOMPRESSING:
		/* TRANSLATORS: decompressing the firmware file */
		return _("Decompressing…");
		break;
	case FWUPD_STATUS_LOADING:
		/* TRANSLATORS: parsing the firmware information */
		return _("Loading…");
		break;
	case FWUPD_STATUS_DEVICE_RESTART:
		/* TRANSLATORS: restarting the device to pick up new F/W */
		return _("Restarting device…");
		break;
	case FWUPD_STATUS_DEVICE_READ:
		/* TRANSLATORS: reading from the flash chips */
		return _("Reading…");
		break;
	case FWUPD_STATUS_DEVICE_WRITE:
		/* TRANSLATORS: writing to the flash chips */
		return _("Writing…");
		break;
	case FWUPD_STATUS_DEVICE_ERASE:
		/* TRANSLATORS: erasing contents of the flash chips */
		return _("Erasing…");
		break;
	case FWUPD_STATUS_DEVICE_VERIFY:
		/* TRANSLATORS: verifying we wrote the firmware correctly */
		return _("Verifying…");
		break;
	case FWUPD_STATUS_SCHEDULING:
		/* TRANSLATORS: scheduling an update to be done on the next boot */
		return _("Scheduling…");
		break;
	case FWUPD_STATUS_DOWNLOADING:
		/* TRANSLATORS: downloading from a remote server */
		return _("Downloading…");
		break;
	case FWUPD_STATUS_WAITING_FOR_AUTH:
		/* TRANSLATORS: waiting for user to authenticate */
		return _("Authenticating…");
		break;
	case FWUPD_STATUS_DEVICE_BUSY:
		/* TRANSLATORS: waiting for device to do something */
		return _("Waiting…");
		break;
	default:
		break;
	}

	/* TRANSLATORS: current daemon status is unknown */
	return _("Unknown");
}

static void
fu_progressbar_erase_line (FuProgressbar *self)
{
	if (!self->interactive)
		return;
	for (guint i = 0; i < self->to_erase; i++)
		g_print ("\b");
	self->to_erase = 0;
}

static gboolean
fu_progressbar_estimate_ready (FuProgressbar *self, guint percentage)
{
	gdouble old;
	gdouble elapsed;

	if (percentage == 0 || percentage == 100)
		return FALSE;

	old = self->last_estimate;
	elapsed = g_timer_elapsed (self->time_elapsed, NULL);
	self->last_estimate = elapsed / percentage * (100 - percentage);

	/* estimate is ready if we have decreased */
	return old > self->last_estimate;
}

static gchar *
fu_progressbar_time_remaining_str (FuProgressbar *self)
{
	/* less than 5 seconds remaining */
	if (self->last_estimate < 5)
		return NULL;

	/* less than 60 seconds remaining */
	if (self->last_estimate < 60) {
		/* TRANSLATORS: time remaining for completing firmware flash */
		return g_strdup (_("Less than one minute remaining"));
	}

	/* more than a minute */
	return g_strdup_printf (ngettext ("%.0f minute remaining",<commit_msg>Reset the progressbar time estimate if the percentage is invalid<commit_after>/*
 * Copyright (C) 2017 <NAME> <<EMAIL>>
 *
 * SPDX-License-Identifier: LGPL-2.1+
 */

#define G_LOG_DOMAIN				"FuProgressBar"

#include "config.h"

#include <glib.h>
#include <glib/gi18n.h>

#include "fu-common.h"
#include "fu-progressbar.h"

static void fu_progressbar_finalize	 (GObject *obj);

struct _FuProgressbar
{
	GObject			 parent_instance;
	FwupdStatus		 status;
	gboolean		 spinner_count_up;	/* chars */
	guint			 spinner_idx;		/* chars */
	guint			 length_percentage;	/* chars */
	guint			 length_status;		/* chars */
	guint			 percentage;
	guint			 to_erase;		/* chars */
	guint			 timer_id;
	gint64			 last_animated;		/* monotonic */
	GTimer			*time_elapsed;
	gdouble			 last_estimate;
	gboolean		 interactive;
};

G_DEFINE_TYPE (FuProgressbar, fu_progressbar, G_TYPE_OBJECT)

static const gchar *
fu_progressbar_status_to_string (FwupdStatus status)
{
	switch (status) {
	case FWUPD_STATUS_IDLE:
		/* TRANSLATORS: daemon is inactive */
		return _("Idle…");
		break;
	case FWUPD_STATUS_DECOMPRESSING:
		/* TRANSLATORS: decompressing the firmware file */
		return _("Decompressing…");
		break;
	case FWUPD_STATUS_LOADING:
		/* TRANSLATORS: parsing the firmware information */
		return _("Loading…");
		break;
	case FWUPD_STATUS_DEVICE_RESTART:
		/* TRANSLATORS: restarting the device to pick up new F/W */
		return _("Restarting device…");
		break;
	case FWUPD_STATUS_DEVICE_READ:
		/* TRANSLATORS: reading from the flash chips */
		return _("Reading…");
		break;
	case FWUPD_STATUS_DEVICE_WRITE:
		/* TRANSLATORS: writing to the flash chips */
		return _("Writing…");
		break;
	case FWUPD_STATUS_DEVICE_ERASE:
		/* TRANSLATORS: erasing contents of the flash chips */
		return _("Erasing…");
		break;
	case FWUPD_STATUS_DEVICE_VERIFY:
		/* TRANSLATORS: verifying we wrote the firmware correctly */
		return _("Verifying…");
		break;
	case FWUPD_STATUS_SCHEDULING:
		/* TRANSLATORS: scheduling an update to be done on the next boot */
		return _("Scheduling…");
		break;
	case FWUPD_STATUS_DOWNLOADING:
		/* TRANSLATORS: downloading from a remote server */
		return _("Downloading…");
		break;
	case FWUPD_STATUS_WAITING_FOR_AUTH:
		/* TRANSLATORS: waiting for user to authenticate */
		return _("Authenticating…");
		break;
	case FWUPD_STATUS_DEVICE_BUSY:
		/* TRANSLATORS: waiting for device to do something */
		return _("Waiting…");
		break;
	default:
		break;
	}

	/* TRANSLATORS: current daemon status is unknown */
	return _("Unknown");
}

static void
fu_progressbar_erase_line (FuProgressbar *self)
{
	if (!self->interactive)
		return;
	for (guint i = 0; i < self->to_erase; i++)
		g_print ("\b");
	self->to_erase = 0;
}

static gboolean
fu_progressbar_estimate_ready (FuProgressbar *self, guint percentage)
{
	gdouble old;
	gdouble elapsed;

	/* now invalid */
	if (percentage == 0 || percentage == 100) {
		g_timer_start (self->time_elapsed);
		self->last_estimate = 0;
		return FALSE;
	}

	old = self->last_estimate;
	elapsed = g_timer_elapsed (self->time_elapsed, NULL);
	self->last_estimate = elapsed / percentage * (100 - percentage);

	/* estimate is ready if we have decreased */
	return old > self->last_estimate;
}

static gchar *
fu_progressbar_time_remaining_str (FuProgressbar *self)
{
	/* less than 5 seconds remaining */
	if (self->last_estimate < 5)
		return NULL;

	/* less than 60 seconds remaining */
	if (self->last_estimate < 60) {
		/* TRANSLATORS: time remaining for completing firmware flash */
		return g_strdup (_("Less than one minute remaining"));
	}

	/* more than a minute */
	return g_strdup_printf (ngettext ("%.0f minute remaining",
{'fraction_non_alphanumeric': 0.11390820584144645, 'fraction_numerical': 0.00737134909596662, 'mean_word_length': 4.15483870967742, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6052212', 'n_tokens_mistral': 2826, 'n_tokens_neox': 2530, 'n_words': 668}