/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details:
 *
 * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org>
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include "mm-gps-serial-port.h"
#include "mm-log.h"

G_DEFINE_TYPE (MMGpsSerialPort, mm_gps_serial_port, MM_TYPE_SERIAL_PORT)

struct _MMGpsSerialPortPrivate {
    /* Trace handler data */
    MMGpsSerialTraceFn callback;
    gpointer user_data;
    GDestroyNotify notify;

    /* Regex for all known traces */
    GRegex *known_traces_regex;
};

/*****************************************************************************/

void
mm_gps_serial_port_add_trace_handler (MMGpsSerialPort *self,
                                      MMGpsSerialTraceFn callback,
                                      gpointer user_data,
                                      GDestroyNotify notify)
{
    g_return_if_fail (MM_IS_GPS_SERIAL_PORT (self));

    if (self->priv->notify)
        self->priv->notify (self->priv->user_data);

    self->priv->callback = callback;
    self->priv->user_data = user_data;
    self->priv->notify = notify;
}

/*****************************************************************************/

static gboolean
remove_eval_cb (const GMatchInfo *match_info,
                GString *result,
                gpointer user_data)
{
    int *result_len = (int *) user_data;
    int start;
    int end;

    if (g_match_info_fetch_pos  (match_info, 0, &start, &end))
        *result_len -= (end - start);

    return FALSE;
}

static gboolean
parse_response (MMSerialPort *port,
                GByteArray *response,
                GError **error)
{
    MMGpsSerialPort *self = MM_GPS_SERIAL_PORT (port);
    gboolean matches;
    GMatchInfo *match_info;
    gchar *str;
    gint result_len;
    guint i;

    for (i = 0; i < response->len; i++) {
        /* If there is any content before the first $,
         * assume it's garbage, and skip it */
        if (response->data[i] == '$') {
            if (i > 0)
                g_byte_array_remove_range (response, 0, i);
            /* else, good, we're already started with $ */
            break;
        }
    }

    matches = g_regex_match_full (self->priv->known_traces_regex,
                                  (const gchar *) response->data,
                                  response->len,
                                  0, 0, &match_info, NULL);

    if (self->priv->callback) {
        while (g_match_info_matches (match_info)) {
            gchar *trace;

            trace = g_match_info_fetch (match_info, 0);
            if (trace) {
                self->priv->callback (self, trace, self->priv->user_data);
                g_free (trace);
            }
            g_match_info_next (match_info, NULL);
        }
    }

    g_match_info_free (match_info);

    if (!matches)
        return FALSE;

    /* Remove matches */
    result_len = response->len;
    str = g_regex_replace_eval (self->priv->known_traces_regex,
                                (const char *) response->data,
                                response->len,
                                0, 0,
                                remove_eval_cb, &result_len, NULL);

    g_byte_array_remove_range (response, 0, response->len);
    g_byte_array_append (response, (const guint8 *) str, result_len);
    g_free (str);

    return TRUE;
}

/*****************************************************************************/

static void
debug_log (MMSerialPort *port, const char *prefix, const char *buf, gsize len)
{
    static GString *debug = NULL;
    const char *s;

    if (!debug)
        debug = g_string_sized_new (256);

    g_string_append (debug, prefix);
    g_string_append (debug, " '");

    s = buf;
    while (len--) {
        if (g_ascii_isprint (*s))
            g_string_append_c (debug, *s);
        else if (*s == '\r')
            g_string_append (debug, "<CR>");
        else if (*s == '\n')
            g_string_append (debug, "<LF>");
        else
            g_string_append_printf (debug, "\\%u", (guint8) (*s & 0xFF));

        s++;
    }

    g_string_append_c (debug, '\'');
    mm_dbg ("(%s): %s", mm_port_get_device (MM_PORT (port)), debug->str);
    g_string_truncate (debug, 0);
}

/*****************************************************************************/

MMGpsSerialPort *
mm_gps_serial_port_new (const char *name)
{
    return MM_GPS_SERIAL_PORT (g_object_new (MM_TYPE_GPS_SERIAL_PORT,
                                             MM_PORT_DEVICE, name,
                                             MM_PORT_SUBSYS, MM_PORT_SUBSYS_TTY,
                                             MM_PORT_TYPE, MM_PORT_TYPE_GPS,
                                             NULL));
}

static void
mm_gps_serial_port_init (MMGpsSerialPort *self)
{
    self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self),
                                              MM_TYPE_GPS_SERIAL_PORT,
                                              MMGpsSerialPortPrivate);

    /* We'll assume that all traces start with the dollar sign and end with \r\n */
    self->priv->known_traces_regex =
        g_regex_new ("\\$.*\\r\\n",
                     G_REGEX_RAW | G_REGEX_OPTIMIZE,
                     0,
                     NULL);
}

static void
finalize (GObject *object)
{
    MMGpsSerialPort *self = MM_GPS_SERIAL_PORT (object);

    if (self->priv->notify)
        self->priv->notify (self->priv->user_data);

    g_regex_unref (self->priv->known_traces_regex);

    G_OBJECT_CLASS (mm_gps_serial_port_parent_class)->finalize (object);
}

static void
mm_gps_serial_port_class_init (MMGpsSerialPortClass *klass)
{
    GObjectClass *object_class = G_OBJECT_CLASS (klass);
    MMSerialPortClass *port_class = MM_SERIAL_PORT_CLASS (klass);

    g_type_class_add_private (object_class, sizeof (MMGpsSerialPortPrivate));

    /* Virtual methods */
    object_class->finalize = finalize;

    port_class->parse_response = parse_response;
    port_class->debug_log = debug_log;
}
