/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright 2024, 2025 GNOME Foundation, Inc.
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Authors:
 *  - Philip Withnall <pwithnall@gnome.org>
 */

#pragma once

#include <gio/gio.h>
#include <glib.h>
#include <glib-object.h>
#include <libmalcontent-timer/time-span.h>

G_BEGIN_DECLS

/**
 * MctTimerStoreRecordType:
 * @MCT_TIMER_STORE_RECORD_TYPE_LOGIN_SESSION: a login session
 * @MCT_TIMER_STORE_RECORD_TYPE_APP: an app
 *
 * Types of records supported by [class@Mct.TimerStore].
 *
 * Each record indicates that the user was using something, such as a particular
 * app, or being logged in to a desktop session (i.e. using the computer at
 * all), for a period of time.
 *
 * Since: 0.14.0
 */
typedef enum {
  MCT_TIMER_STORE_RECORD_TYPE_LOGIN_SESSION,
  MCT_TIMER_STORE_RECORD_TYPE_APP,
} MctTimerStoreRecordType;

const char *mct_timer_store_record_type_to_string (MctTimerStoreRecordType record_type);
MctTimerStoreRecordType mct_timer_store_record_type_from_string (const char *str);
gboolean mct_timer_store_record_type_validate_string (const char  *record_type_str,
                                                      GError     **error);
gboolean mct_timer_store_record_type_validate_identifier (MctTimerStoreRecordType   record_type,
                                                          const char               *identifier,
                                                          GError                  **error);

/**
 * MctTimerStoreTransaction:
 *
 * Opaque handle for an open and pending transaction to modify data in
 * [class@Mct.TimerStore].
 *
 * A transaction must either be saved using
 * [method@Mct.TimerStore.save_transaction_async] or cancelled using
 * [method@Mct.TimerStore.roll_back_transaction]. There is no other way of
 * freeing one.
 *
 * Since: 0.14.0
 */
typedef void MctTimerStoreTransaction;

#define MCT_TYPE_TIMER_STORE mct_timer_store_get_type ()
G_DECLARE_FINAL_TYPE (MctTimerStore, mct_timer_store, MCT, TIMER_STORE, GObject)

MctTimerStore *mct_timer_store_new (GFile *store_directory);

GFile *mct_timer_store_get_store_directory (MctTimerStore *self);

void mct_timer_store_open_username_async (MctTimerStore       *self,
                                          const char          *username,
                                          GCancellable        *cancellable,
                                          GAsyncReadyCallback  callback,
                                          void                *user_data);
const MctTimerStoreTransaction *mct_timer_store_open_username_finish (MctTimerStore  *self,
                                                                      GAsyncResult   *result,
                                                                      GError        **error);
void mct_timer_store_save_transaction_async (MctTimerStore                  *self,
                                             const MctTimerStoreTransaction *transaction,
                                             uint64_t                        expiry_cutoff_secs,
                                             GCancellable                   *cancellable,
                                             GAsyncReadyCallback             callback,
                                             void                           *user_data);
gboolean mct_timer_store_save_transaction_finish (MctTimerStore  *self,
                                                  GAsyncResult   *result,
                                                  GError        **error);
void mct_timer_store_roll_back_transaction (MctTimerStore                  *self,
                                            const MctTimerStoreTransaction *transaction);

void mct_timer_store_add_time_spans (MctTimerStore                  *self,
                                     const MctTimerStoreTransaction *transaction,
                                     MctTimerStoreRecordType         record_type,
                                     const char                     *identifier,
                                     const MctTimeSpan * const      *time_spans,
                                     size_t                          n_time_spans);

GHashTable *mct_timer_store_calculate_total_times_between (MctTimerStore                  *self,
                                                           const MctTimerStoreTransaction *transaction,
                                                           MctTimerStoreRecordType         record_type,
                                                           uint64_t                        since_secs,
                                                           uint64_t                        until_secs);

const MctTimeSpan * const *mct_timer_store_query_time_spans (MctTimerStore                  *self,
                                                             const MctTimerStoreTransaction *transaction,
                                                             MctTimerStoreRecordType         record_type,
                                                             const char                     *identifier,
                                                             size_t                         *out_n_time_spans);

G_END_DECLS
