// Copyright 2015 by Artem Prilutskiy

#include "BrandMeisterBridge.h"
#include <string.h>
#include <stdlib.h>
#include <syslog.h>
#include <stdio.h>

#define ECHOLINK_DEFAULT_USER_CALL    "N0CALL Unknown call"
#define ECHOLINK_DEFAULT_USER_NUMBER  1

#define DELETE(object)  \
  if (object)           \
  delete object;

BrandMeisterBridge::BrandMeisterBridge()
{
  proxy = NULL;
  talker = NULL;
  unknown = ECHOLINK_DEFAULT_USER_NUMBER;
}

BrandMeisterBridge::~BrandMeisterBridge()
{
  DELETE(proxy);
  free(talker);
}

// Interface methods for ModuleEchoLink

void BrandMeisterBridge::setDefaultConfiguration(const char* configuration)
{
  unknown = strtol(configuration, NULL, 10);
}

void BrandMeisterBridge::setProxyConfiguration(const char* configuration)
{
  char* pointer = const_cast<char*>(configuration);
  // <Network ID>:<PatchCord ID>
  uint32_t network = strtol(pointer + 0, &pointer, 10);
  uint32_t link    = strtol(pointer + 1, &pointer, 10);
  proxy = new PatchCord(network, link);
}

const char* BrandMeisterBridge::getTalker()
{
  if (proxy == NULL)
  {
    syslog(LOG_ERR, "BrandMeister bridge is not configured");
    return ECHOLINK_DEFAULT_USER_CALL;
  }

  free(talker);
  uint32_t number = proxy->getTalkerID();

  char call[16];
  char text[48];
  if ((number != 0) &&
      (proxy->getCredentialsForID(number, call, text)))
  {
    asprintf(&talker, "%s %s", call, text);
    return talker;
  }

  asprintf(&talker, "DMR ID: %d", number);
  return talker;
}

void BrandMeisterBridge::setTalker(const char* call, const char* name)
{
  if (proxy == NULL)
  {
    syslog(LOG_ERR, "BrandMeister bridge is not configured");
    return;
  }

  if (*call == '*')
  {
    // Do not process conference call-sign
    return;
  }

  const char* delimiter1 = strpbrk(call, " -\n");
  const char* delimiter2 = strpbrk(name, "\n");

  if (delimiter1 != NULL)
  {
    // Remove characters after call-sign
    size_t length = delimiter1 - call;
    char* buffer = (char*)alloca(length + sizeof(uint32_t));
    strncpy(buffer, call, length);
    buffer[length] = '\0';
    call = buffer;
  }
  if (delimiter2 != NULL)
  {
    // Remove characters after talker name
    size_t length = delimiter2 - name;
    char* buffer = (char*)alloca(length + sizeof(uint32_t));
    strncpy(buffer, name, length);
    buffer[length] = '\0';
    name = buffer;
  }

  uint32_t number = proxy->getPrivateIDForCall(call);
  if (number == 0)
    number = unknown;

  syslog(LOG_INFO, "Set talker ID to %d for call-sign %s (%s)", number, call, name);
  proxy->setTalkerID(number);
  proxy->setTalkerAlias(name);
}

void BrandMeisterBridge::handleChatMessage(const char* text)
{
  // CONF Russian Reflector, Open 24/7, Contacts: rv3dhc.link@qip.ru * Call CQ / Use pauses 2sec * [28/500]
  // R3ABM-L *DSTAR.SU DMR Bridge*
  // UB3AMO Moscow T I N A O
  // ->UA0LQE-L USSURIISK

  if (proxy == NULL)
  {
    syslog(LOG_ERR, "BrandMeister bridge is not configured");
    return;
  }

  if (strncmp(text, "CONF ", 5) == 0)
  {
    const char* delimiter = strstr(text, "\n->");
    if (delimiter != NULL)
    {
      const char* call = delimiter + 3;
      setTalker(call, call);
    }
    else
    {
      syslog(LOG_INFO, "Set talker ID to %d (call-sign was not fit into chat message)", unknown);
      proxy->setTalkerID(unknown);
      proxy->setTalkerAlias("");
    }
  }
}