/*
 * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#define _POSIX_C_SOURCE 201108L
#define _XOPEN_SOURCE 600

#include <assert.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>

#include <glib.h>
#include <dbus/dbus-glib.h>

GIOChannel* ioc;
int masterfd;

typedef struct {
  GRegex *command;
  char *reply; // generic text
  char *responsetext; // ERROR, +CMS ERROR, etc.
} Pattern;

typedef struct _FakeModem {
  GObject parent;
  gboolean echo;
  gboolean verbose;
  GPtrArray *patterns;
} FakeModem;

typedef struct _FakeModemClass
{
  GObjectClass parent_class;
} FakeModemClass;

GType fakemodem_get_type (void) G_GNUC_CONST;

#define FAKEMODEM_TYPE         (fake_modem_get_type ())
#define FAKEMODEM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), FAKEMODEM_TYPE, FakeModem))

G_DEFINE_TYPE (FakeModem, fake_modem, G_TYPE_OBJECT)

static void
fake_modem_init (FakeModem* self)
{

  self->echo = TRUE;
  self->verbose = TRUE;
  self->patterns = NULL;
}

static void
fake_modem_class_init (FakeModemClass* self)
{
}

static gboolean master_read (GIOChannel *source, GIOCondition condition,
                             gpointer data);

static const gchar *handle_cmd (FakeModem *fakemodem, const gchar *cmd);

static gboolean send_unsolicited (FakeModem* fakemodem, const gchar* text);
static gboolean set_response (FakeModem* fakemodem, const gchar* command,
                              const gchar* reply, const gchar* response);
static gboolean remove_response (FakeModem* fakemodem, const gchar* command);

#include "fakemodem-dbus.h"

GPtrArray *
parse_pattern_files(char **pattern_files, GError **error)
{
  gint linenum;
  GRegex *skip, *parts;
  GPtrArray *patterns;
  int i;

  patterns = g_ptr_array_new();

  skip = g_regex_new ("^\\s*(#.*)?$", 0, 0, error);
  if (skip == NULL)
    return NULL;
  parts = g_regex_new ("^(\\S+)\\s*(\"([^\"]*)\")?\\s*(.*)$", 0, 0, error);
  if (parts == NULL)
    return NULL;

  for (i = 0 ; pattern_files[i] != NULL; i++) {
    GIOChannel *pf;
    gchar *pattern_file;
    gchar *line;
    gsize len, term;

    pattern_file = pattern_files[i];

    pf = g_io_channel_new_file (pattern_file, "r", error);
    if (pf == NULL)
      return NULL;

    linenum = 0;
    while (g_io_channel_read_line (pf, &line, &len, &term, error) ==
           G_IO_STATUS_NORMAL) {
      /* Don't need the terminator */
      line[term] = '\0';
      linenum++;

      if (!g_regex_match (skip, line, 0, NULL)) {
        GMatchInfo *info;
        gboolean ret;
        gchar *command, *responsetext;
        ret = g_regex_match (parts, line, 0, &info);
        if (ret) {
          Pattern *pat;
          pat = g_malloc (sizeof (*pat));
          command = g_match_info_fetch (info, 1);
          pat->command = g_regex_new (command,
                                      G_REGEX_ANCHORED |
                                      G_REGEX_CASELESS |
                                      G_REGEX_RAW |
                                      G_REGEX_OPTIMIZE,
                                      0,
                                      error);
          g_free (command);
          if (pat->command == NULL) {
            printf ("error: %s\n", (*error)->message);
            g_error_free (*error);
            *error = NULL;
          }
          responsetext = g_match_info_fetch (info, 3);
          if (strlen (responsetext) == 0) {
            g_free (responsetext);
            responsetext = NULL;
          }
          pat->responsetext = responsetext;
          pat->reply = g_match_info_fetch (info, 4);
          while (pat->reply[strlen (pat->reply) - 1] == '\\') {
            gchar *origstr;
            pat->reply[strlen (pat->reply) - 1] = '\0';
            g_free (line); /* probably invalidates fields in 'info' */
            g_io_channel_read_line (pf, &line, &len, &term, error);
            line[term] = '\0';
            linenum++;
            origstr = pat->reply;
            pat->reply = g_strjoin ("\r\n", origstr, line, NULL);
            g_free (origstr);
          }
          g_ptr_array_add (patterns, pat);
        } else {
          printf (" Line %d '%s' was not parsed"
                  " as a command-response pattern\n",
                  linenum, line);
        }
        g_match_info_free (info);
      }
      g_free (line);
    }
    g_io_channel_shutdown (pf, TRUE, NULL);
  }

  g_regex_unref (skip);
  g_regex_unref (parts);

  return patterns;
}

#define FM_DBUS_SERVICE "org.chromium.FakeModem"

static DBusGProxy *
create_dbus_proxy (DBusGConnection *bus)
{
    DBusGProxy *proxy;
    GError *err = NULL;
    int request_name_result;

    proxy = dbus_g_proxy_new_for_name (bus,
                                       "org.freedesktop.DBus",
                                       "/org/freedesktop/DBus",
                                       "org.freedesktop.DBus");

    if (!dbus_g_proxy_call (proxy, "RequestName", &err,
                            G_TYPE_STRING, FM_DBUS_SERVICE,
                            G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE,
                            G_TYPE_INVALID,
                            G_TYPE_UINT, &request_name_result,
                            G_TYPE_INVALID)) {
        g_print ("Could not acquire the %s service.\n"
                 "  Message: '%s'\n", FM_DBUS_SERVICE, err->message);

        g_error_free (err);
        g_object_unref (proxy);
        proxy = NULL;
    } else if (request_name_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
        g_print ("Could not acquire the " FM_DBUS_SERVICE
                 " service as it is already taken. Return: %d\n",
                 request_name_result);

        g_object_unref (proxy);
        proxy = NULL;
    } else {
        dbus_g_proxy_add_signal (proxy, "NameOwnerChanged",
                                 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
                                 G_TYPE_INVALID);
    }

    return proxy;
}

int
main (int argc, char *argv[])
{
  DBusGConnection *bus;
  DBusGProxy *proxy;
  GMainLoop* loop;
  const char *slavedevice;
  struct termios t;
  FakeModem *fakemodem;
  GOptionContext *opt_ctx;
  char **pattern_files = NULL;
  gboolean session = FALSE;
  GError *err = NULL;

  GOptionEntry entries[] = {
    { "patternfile", 0, 0, G_OPTION_ARG_STRING_ARRAY, &pattern_files,
      "Path to pattern file", NULL},
    { "session", 0, 0, G_OPTION_ARG_NONE, &session,
      "Bind to session bus", NULL},
    { "system", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &session,
      "Bind to system bus (default)", NULL},
    { NULL }
  };

  g_type_init ();

  opt_ctx = g_option_context_new (NULL);
  g_option_context_set_summary (opt_ctx,
                                "Emulate a modem with a set of "
                                "regexp-programmed responses.");
  g_option_context_add_main_entries (opt_ctx, entries, NULL);
  if (!g_option_context_parse (opt_ctx, &argc, &argv, &err)) {
    g_warning ("%s\n", err->message);
    g_error_free (err);
    exit (1);
  }

  g_option_context_free (opt_ctx);

  fakemodem = g_object_new (FAKEMODEM_TYPE, NULL);
  if (pattern_files) {
    fakemodem->patterns = parse_pattern_files (pattern_files, &err);
    if (fakemodem->patterns == NULL) {
      g_warning ("%s\n", err->message);
      g_error_free (err);
      exit (1);
    }
  } else
    fakemodem->patterns = g_ptr_array_sized_new (0);

  loop = g_main_loop_new (NULL, FALSE);

  dbus_g_object_type_install_info (FAKEMODEM_TYPE,
                                   &dbus_glib_fakemodem_object_info);

  err = NULL;
  if (session)
    bus = dbus_g_bus_get (DBUS_BUS_SESSION, &err);
  else
    bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);

  if (bus == NULL) {
      g_warning ("%s\n", err->message);
      g_error_free (err);
      exit (1);
  }

  proxy = create_dbus_proxy (bus);
  if (!proxy)
    exit (1);

  dbus_g_connection_register_g_object (bus,
                                       "/",
                                       G_OBJECT (fakemodem));

  masterfd = posix_openpt (O_RDWR | O_NOCTTY);

  if (masterfd == -1
      || grantpt (masterfd) == -1
      || unlockpt (masterfd) == -1
      || (slavedevice = ptsname (masterfd)) == NULL)
    exit (1);

  printf ("%s\n", slavedevice);
  fflush (stdout);

  /* Echo is actively harmful here */
  tcgetattr (masterfd, &t);
  t.c_lflag &= ~ECHO;
  tcsetattr (masterfd, TCSANOW, &t);

  ioc = g_io_channel_unix_new (masterfd);
  g_io_channel_set_encoding (ioc, NULL, NULL);
  g_io_channel_set_line_term (ioc, "\r", 1);
  g_io_add_watch (ioc, G_IO_IN, master_read, fakemodem);

  g_main_loop_run (loop);

  g_main_loop_unref (loop);

  g_object_unref (fakemodem);
  return 0;
}


/*
 * &?[A-CE-RT-Z][0-9]*
 * S[0-9]+?
 * S[0-9]+=(([0-9A-F]+|"[^"]*")?,)+
 */

/*
 * action +[A-Z][A-Z0-9%-./:_]{0,15}
 * test   +[A-Z][A-Z0-9%-./:_]{0,15}=?
 * get    +[A-Z][A-Z0-9%-./:_]{0,15}?
 * set    +[A-Z][A-Z0-9%-./:_]{0,15}=(([0-9A-F]+|"[^"]*")?,)+
 */


#define VALUE "([0-9A-F]+|\"[^\"]*\")"
#define CVALUE VALUE "?(," VALUE "?)*"
static char *command_patterns[] =
{"\\s*(&?[A-CE-RT-Z][0-9]*)",
 "\\s*(S[0-9]+\\?)",
 "\\s*(S[0-9]+=" CVALUE ")",
 /* ATD... (dial string) handling is missing */
 "\\s*;?\\s*([+*%&][A-Z][A-Z0-9%-./:_]{0,15}=\\?)",
 "\\s*;?\\s*([+*%&][A-Z][A-Z0-9%-./:_]{0,15}=" CVALUE ")",
 "\\s*;?\\s*([+*%&][A-Z][A-Z0-9%-./:_]{0,15}(\\?)?)",
};

#undef VALUE
#undef CVALUE

static gboolean master_read (GIOChannel *source, GIOCondition condition,
                             gpointer data)
{
  FakeModem *fakemodem = data;
  gchar *line, *next;
  const gchar *response;
  gsize term;
  GError *error = NULL;
  GIOStatus status;
  int i, rval;

  static GPtrArray *commands;

  if (commands == NULL) {
    int n;
    n = sizeof (command_patterns) / sizeof (command_patterns[0]);
    commands = g_ptr_array_sized_new (n);
    for (i = 0 ; i < n ; i++) {
      GRegex *re = g_regex_new (command_patterns[i],
                                G_REGEX_CASELESS |
                                G_REGEX_ANCHORED |
                                G_REGEX_RAW |
                                G_REGEX_OPTIMIZE,
                                0,
                                &error);
      if (re == NULL) {
        g_warning ("Couldn't generate command regex: %s\n", error->message);
        g_error_free (error);
        exit (1);
      }
      g_ptr_array_add (commands, re);
    }
  }

  status = g_io_channel_read_line (source, &line, NULL, &term, &error);
  if (status == G_IO_STATUS_ERROR)
    return FALSE;
  line[term] = '\0';

  printf ("Line: '%s'\n", line);

  if (fakemodem->echo) {
    rval = write (masterfd, line, term);
    assert(term == rval);
    rval = write (masterfd, "\r\n", 2);
    assert(2 == rval);
  }

  if (g_ascii_strncasecmp (line, "AT", 2) != 0) {
    if (line[0] == '\0')
      goto out;
    response = "ERROR";
    goto done;
  }

  response = NULL;
  next = line + 2;

  while (!response && *next) {
    for (i = 0 ; i < commands->len; i++) {
      GMatchInfo *info;
      if (g_regex_match (g_ptr_array_index (commands, i), next, 0, &info)) {
        gint start, end;
        gchar *cmd;
        g_match_info_fetch_pos (info, 1, &start, &end);
        cmd = g_strndup (next + start, end - start);
        response = handle_cmd (fakemodem, cmd);
        g_free (cmd);
        g_match_info_free (info);
        next += end;
        break;
      }
      g_match_info_free (info);
    }
    if (i == commands->len) {
      response = "ERROR";
      break;
    }
  }


done:
  if (fakemodem->verbose) {
    gchar *rstr;
    if (response == NULL)
      response = "OK";
    rstr = g_strdup_printf("\r\n%s\r\n", response);
    rval = write (masterfd, rstr, strlen (rstr));
    assert(strlen(rstr) == rval);
    g_free (rstr);
  } else {
    gchar *rstr;
    rstr = g_strdup_printf("%s\n", response);
    rval = write (masterfd, rstr, strlen (rstr));
    assert(strlen(rstr) == rval);
    g_free (rstr);
  }

out:
  g_free (line);
  return TRUE;
}

static const gchar *
handle_cmd(FakeModem *fakemodem, const gchar *cmd)
{
  guint i;
  Pattern *pat;

  printf (" Cmd:  '%s'\n", cmd);

  if (toupper (cmd[0]) >= 'A' && toupper (cmd[0]) <= 'Z') {
    switch (toupper (cmd[0])) {
      case 'E':
        if (cmd[1] == '0')
          fakemodem->echo = FALSE;
        else if (cmd[1] == '1')
          fakemodem->echo = TRUE;
        else
          return "ERROR";
        return "OK";
      case 'V':
        if (cmd[1] == '0')
          fakemodem->verbose = FALSE;
        else if (cmd[1] == '1')
          fakemodem->verbose = TRUE;
        else
          return "ERROR";
        return "OK";
      case 'Z':
        fakemodem->echo = TRUE;
        fakemodem->verbose = TRUE;
        return "OK";
    }
  }

  for (i = 0 ; i < fakemodem->patterns->len; i++) {
    pat = (Pattern *)g_ptr_array_index (fakemodem->patterns, i);
    if (g_regex_match (pat->command, cmd, 0, NULL)) {
      break;
    }
  }

  if (i == fakemodem->patterns->len)
    return "ERROR";

  if (pat->reply && pat->reply[0]) {
    int rval;
    printf (" Reply: '%s'\n", pat->reply);
    rval = write (masterfd, pat->reply, strlen (pat->reply));
    assert(strlen(pat->reply) == rval);
    rval = write (masterfd, "\r\n", 2);
    assert(2 == rval);
  }

  return pat->responsetext; /* NULL implies "OK" and keep processing */
}


static gboolean
send_unsolicited (FakeModem *fakemodem, const gchar* text)
{
  int rval;

  rval = write (masterfd, "\r\n", 2);
  rval = write (masterfd, text, strlen (text));
  assert(strlen(text) == rval);
  rval = write (masterfd, "\r\n", 2);
  assert(2 == rval);

  return TRUE;
}

static gboolean
set_response (FakeModem *fakemodem,
              const gchar* command,
              const gchar* reply,
              const gchar* response)
{
  int i;
  Pattern *pat;

  if (strlen (response) == 0)
    response = "OK";

  for (i = 0 ; i < fakemodem->patterns->len; i++) {
    pat = (Pattern *)g_ptr_array_index (fakemodem->patterns, i);
    if (strcmp (g_regex_get_pattern (pat->command), command) == 0) {
      g_free (pat->reply);
      pat->reply = g_strdup (reply);
      g_free (pat->responsetext);
      pat->responsetext = g_strdup (response);
      break;
    }
  }

  if (i == fakemodem->patterns->len) {
    GError *error = NULL;
    pat = g_malloc (sizeof (*pat));
    pat->command = g_regex_new (command,
                                G_REGEX_ANCHORED |
                                G_REGEX_CASELESS |
                                G_REGEX_RAW |
                                G_REGEX_OPTIMIZE,
                                0,
                                &error);
    if (pat->command == NULL) {
      printf ("error: %s\n", error->message);
      g_free (pat);
      return FALSE;
    }
    pat->responsetext = g_strdup (response);
    pat->reply = g_strdup (reply);
    g_ptr_array_add (fakemodem->patterns, pat);
  }

  return TRUE;
}

static gboolean
remove_response (FakeModem* fakemodem, const gchar* command)
{
  int i;
  gboolean found;
  Pattern *pat;

  found = FALSE;
  for (i = 0 ; i < fakemodem->patterns->len; i++) {
    pat = (Pattern *)g_ptr_array_index (fakemodem->patterns, i);
    if (strcmp (g_regex_get_pattern (pat->command), command) == 0) {
      g_ptr_array_remove_index (fakemodem->patterns, i);
      found = TRUE;
      break;
    }
  }

  return found;
}
