<commit_before>/**
 * @author <NAME> <<EMAIL>>
 */
#ifndef SLASTFM_H
#define SLASTFM_H

#include <lastfmlib/lastfmscrobblerc.h>
#include <time.h>

#define API_KEY "990909c4e451d6c1ee3df4f5ee87e6f4"
#define API_SECRET "8bde8774564ef206edd9ef9722742a72"
#define LASTFM_NOW_PLAYING_DELAY 65 //seconds
#define LASTFM_MIN_TRACK_LENGTH 30 // seconds

int _log(log_level level, const char* format, ...);

#if 0
const char* get_lastfm_status_label (lastfm_call_status status)
{
    switch (status) {
        case ok:
            return "ok";
        case unavaliable:
            return "The service is temporarily unavailable, please try again.";
        case invalid_service:
            return "Invalid service - This service does not exist";
        case invalid_method:
            return "Invalid Method - No method with that name in this package";
        case authentication_failed:
            return "Authentication Failed - You do not have permissions to access the service";
        case invalid_format:
            return "Invalid format - This service doesn't exist in that format";
        case invalid_parameters:
            return "Invalid parameters - Your request is missing a required parameter";
        case invalid_resource:
            return "Invalid resource specified";
        case operation_failed:
            return "Operation failed - Something else went wrong";
        case invalid_session_key:
            return "Invalid session key - Please re-authenticate";
        case invalid_apy_key:
            return "Invalid API key - You must be granted a valid key by last.fm";
        case service_offline:
            return "Service Offline - This service is temporarily offline. Try again later.";
        case invalid_signature:
            return "Invalid method signature supplied";
        case temporary_error:
            return "There was a temporary error processing your request. Please try again";
        case suspended_api_key:
            return "Suspended API key - Access for your account has been suspended, please contact Last.fm";
        case rate_limit_exceeded:
            return "Rate limit exceeded - Your IP has made too many requests in a short period";
    }
    return "Unkown";
}
#endif

lastfm_scrobbler* lastfm_create_scrobbler(char* user_name, char* password)
{
    lastfm_scrobbler *s = create_scrobbler(user_name, password, 0, 1);

    if (NULL == s) {
        _log(error, "last.fm::login: failed");
        return NULL;
    } else {
        _log(debug, "last.fm::login: ok", "ok");
    }
    return s;
}

void lastfm_destroy_scrobbler(lastfm_scrobbler *s)
{
    if (NULL == s) { return; }
    destroy_scrobbler(s);
}

void scrobble_init(scrobble *s)
{
    if (NULL == s) { return; }
    //if (NULL != s->title) { free(s->title); }
    s->title = NULL;
    //if (NULL != s->album) { free(s->album); }
    s->album = NULL;
    //if (NULL != s->artist) { free(s->artist); }
    s->artist = NULL;
    s->scrobbled = false;
    s->length = 0;
    s->position = 0;
    s->start_time = 0;
    s->track_number = 0;

    _log(tracing, "mem::inited_scrobble(%p)", s);
}

void scrobble_free(scrobble *s)
{
    if (NULL == s) return;

    if (NULL != s->title) { free(s->title); }
    if (NULL != s->album) { free(s->album); }
    if (NULL != s->artist) { free(s->artist); }

    _log (tracing, "mem::freeing_scrobble(%p)", s);
    free(s);
}

void events_free(events *);
void dbus_close(state *);
void state_free(state *s)
{
    _log(tracing, "mem::freeing_state(%p)::queue_length:%u", s, s->queue_length);
    for (unsigned i = 0; i < s->queue_length; i++) {
        scrobble_free(s->queue[i]);
    }
    if (NULL != s->current) { scrobble_free(s->current); }
    if (NULL != s->properties) { mpris_properties_unref(s->properties); }
    if (NULL != s->dbus) { dbus_close(s); }
    if (NULL != s->events) { events_free(s->events); }

    lastfm_destroy_scrobbler(s->scrobbler);
    free(s);
}

events* events_new();
dbus *dbus_connection_init(state*);
void get_mpris_properties(DBusConnection*, const char*, mpris_properties*);
void get_player_namespace(DBusConnection*, char**);

void state_init(state *s)
{
    extern lastfm_credentials credentials;
    s->queue_length = 0;
    s->player_state = stopped;
    s->scrobbler = lastfm_create_scrobbler(credentials.user_name, credentials.password);

    s->current = malloc(sizeof(scrobble));
    scrobble_init(s->current);

    s->properties = malloc(sizeof(mpris_properties));
    mpris_properties_init(s->properties);

    s->events = events_new();
    s->dbus = dbus_connection_init(s);

    char* destination = NULL;//get_zero_string(MAX_PROPERTY_LENGTH);
    get_player_namespace(s->dbus->conn, &destination);
    if (NULL == destination ) { return; }
    get_mpris_properties(s->dbus->conn, destination, s->properties);

    _log(tracing, "mem::inited_state(%p)", s);
}

state* state_new()
{
    state *result = malloc(sizeof(state));
    if (NULL == result) { return NULL; }

    state_init(result);

    return result;
}

bool scrobble_is_valid(const scrobble *s)
{
    if (NULL == s) { return false; }
    if (NULL == s->title) { return false; }
    if (NULL == s->album) { return false; }
    if (NULL == s->artist) { return false; }
    if (s->scrobbled) { return false; }
#if 0
    _log(tracing, "Checking playtime: %u - %u", s->play_time, (s->length / 2));<commit_msg>Adding properties check at start time<commit_after>/**
 * @author <NAME> <<EMAIL>>
 */
#ifndef SLASTFM_H
#define SLASTFM_H

#include <lastfmlib/lastfmscrobblerc.h>
#include <time.h>

#define API_KEY "990909c4e451d6c1ee3df4f5ee87e6f4"
#define API_SECRET "8bde8774564ef206edd9ef9722742a72"
#define LASTFM_NOW_PLAYING_DELAY 65 //seconds
#define LASTFM_MIN_TRACK_LENGTH 30 // seconds

int _log(log_level level, const char* format, ...);

#if 0
const char* get_lastfm_status_label (lastfm_call_status status)
{
    switch (status) {
        case ok:
            return "ok";
        case unavaliable:
            return "The service is temporarily unavailable, please try again.";
        case invalid_service:
            return "Invalid service - This service does not exist";
        case invalid_method:
            return "Invalid Method - No method with that name in this package";
        case authentication_failed:
            return "Authentication Failed - You do not have permissions to access the service";
        case invalid_format:
            return "Invalid format - This service doesn't exist in that format";
        case invalid_parameters:
            return "Invalid parameters - Your request is missing a required parameter";
        case invalid_resource:
            return "Invalid resource specified";
        case operation_failed:
            return "Operation failed - Something else went wrong";
        case invalid_session_key:
            return "Invalid session key - Please re-authenticate";
        case invalid_apy_key:
            return "Invalid API key - You must be granted a valid key by last.fm";
        case service_offline:
            return "Service Offline - This service is temporarily offline. Try again later.";
        case invalid_signature:
            return "Invalid method signature supplied";
        case temporary_error:
            return "There was a temporary error processing your request. Please try again";
        case suspended_api_key:
            return "Suspended API key - Access for your account has been suspended, please contact Last.fm";
        case rate_limit_exceeded:
            return "Rate limit exceeded - Your IP has made too many requests in a short period";
    }
    return "Unkown";
}
#endif

lastfm_scrobbler* lastfm_create_scrobbler(char* user_name, char* password)
{
    lastfm_scrobbler *s = create_scrobbler(user_name, password, 0, 1);

    if (NULL == s) {
        _log(error, "last.fm::login: failed");
        return NULL;
    } else {
        _log(debug, "last.fm::login: ok", "ok");
    }
    return s;
}

void lastfm_destroy_scrobbler(lastfm_scrobbler *s)
{
    if (NULL == s) { return; }
    destroy_scrobbler(s);
}

void scrobble_init(scrobble *s)
{
    if (NULL == s) { return; }
    //if (NULL != s->title) { free(s->title); }
    s->title = NULL;
    //if (NULL != s->album) { free(s->album); }
    s->album = NULL;
    //if (NULL != s->artist) { free(s->artist); }
    s->artist = NULL;
    s->scrobbled = false;
    s->length = 0;
    s->position = 0;
    s->start_time = 0;
    s->track_number = 0;

    _log(tracing, "mem::inited_scrobble(%p)", s);
}

void scrobble_free(scrobble *s)
{
    if (NULL == s) return;

    if (NULL != s->title) { free(s->title); }
    if (NULL != s->album) { free(s->album); }
    if (NULL != s->artist) { free(s->artist); }

    _log (tracing, "mem::freeing_scrobble(%p)", s);
    free(s);
}

void events_free(events *);
void dbus_close(state *);
void state_free(state *s)
{
    _log(tracing, "mem::freeing_state(%p)::queue_length:%u", s, s->queue_length);
    for (unsigned i = 0; i < s->queue_length; i++) {
        scrobble_free(s->queue[i]);
    }
    if (NULL != s->current) { scrobble_free(s->current); }
    if (NULL != s->properties) { mpris_properties_unref(s->properties); }
    if (NULL != s->dbus) { dbus_close(s); }
    if (NULL != s->events) { events_free(s->events); }

    lastfm_destroy_scrobbler(s->scrobbler);
    free(s);
}

events* events_new();
dbus *dbus_connection_init(state*);
void get_mpris_properties(DBusConnection*, const char*, mpris_properties*);
bool get_player_namespace(DBusConnection*, char**);
void state_loaded_properties(state* , mpris_properties*);
void state_init(state *s)
{
    extern lastfm_credentials credentials;
    s->queue_length = 0;
    s->player_state = stopped;
    s->scrobbler = lastfm_create_scrobbler(credentials.user_name, credentials.password);

    s->current = malloc(sizeof(scrobble));
    scrobble_init(s->current);

    s->properties = malloc(sizeof(mpris_properties));
    mpris_properties_init(s->properties);

    s->events = events_new();
    s->dbus = dbus_connection_init(s);

    char* destination = NULL;//get_zero_string(MAX_PROPERTY_LENGTH);
    get_player_namespace(s->dbus->conn, &destination);
    if (NULL == destination ) { return; }
    mpris_properties *properties = mpris_properties_new();
    get_mpris_properties(s->dbus->conn, destination, properties);
    state_loaded_properties(s, properties);
    mpris_properties_unref(properties);

    _log(tracing, "mem::inited_state(%p)", s);
}

state* state_new()
{
    state *result = malloc(sizeof(state));
    if (NULL == result) { return NULL; }

    state_init(result);

    return result;
}

bool scrobble_is_valid(const scrobble *s)
{
    if (NULL == s) { return false; }
    if (NULL == s->title) { return false; }
    if (NULL == s->album) { return false; }
    if (NULL == s->artist) { return false; }
    if (s->scrobbled) { return false; }
#if 0
    _log(tracing, "Checking playtime: %u - %u", s->play_time, (s->length / 2));
{'fraction_non_alphanumeric': 0.12978975152452898, 'fraction_numerical': 0.010011832165286247, 'mean_word_length': 3.1605452480121166, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 114, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2678072', 'n_tokens_mistral': 3689, 'n_tokens_neox': 3573, 'n_words': 931}