/*
 * Copyright (c) 2012 Netflix, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY NETFLIX, INC. AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NETFLIX OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <unistd.h>

#include "mongoose.h"

// TODO: Partners should define this port
#define SSDP_PORT (56790)


static char gBuf[4096];

// TODO: Partners should get the friendlyName from the system and insert here.
// TODO: Partners should ensure the friendlyName is the same string returned
//       in the ISsystem::getFriendlyName DPI function.
// TODO: Partners should get the UUID from the system and insert here.
// TODO: Partners should ensure the modelName is identifiably similar to the
//       model name returned in the ISystem::getDeviceModel DPI function
static const char ddxml[] = ""
"<?xml version=\"1.0\"?>"
"<root"
"  xmlns=\"urn:schemas-upnp-org:device-1-0\""
"  xmlns:r=\"urn:restful-tv-org:schemas:upnp-dd\">"
"  <specVersion>"
"    <major>1</major>"
"    <minor>0</minor>"
"  </specVersion>"
"  <device>"
"    <deviceType>urn:schemas-upnp-org:device:tvdevice:1</deviceType>"
"    <friendlyName>%s</friendlyName>"
"    <manufacturer> </manufacturer>"
"    <modelName>%s</modelName>"
"    <UDN>uuid:%s</UDN>"
"  </device>"
"</root>";

// TODO: Partners should get the UUID from the system and insert here.
static const char ssdp_reply[] = "HTTP/1.1 200 OK\r\n"
                         "LOCATION: http://%s:%d/dd.xml\r\n"
                         "CACHE-CONTROL: max-age=1800\r\n"
                         "EXT:\r\n"
                         "BOOTID.UPNP.ORG: 1\r\n"
                         "SERVER: Linux/2.6 UPnP/1.0 quick_ssdp/1.0\r\n"
                         "ST: urn:dial-multiscreen-org:service:dial:1\r\n"
                         "USN: uuid:%s::"
                         "urn:dial-multiscreen-org:service:dial:1\r\n\r\n";


static char ip_addr[INET_ADDRSTRLEN] = "127.0.0.1";
static int dial_port = 0;
static int my_port = 0;
static char friendly_name[256];
static char uuid[256];
static char model_name[256];
static struct mg_context *ctx;

extern int dial_allowed();

static void *request_handler(enum mg_event event,
                             struct mg_connection *conn,
                             const struct mg_request_info *request_info) {
  if (event == MG_NEW_REQUEST) {
    if (!dial_allowed())
          return "done";
    if (!strcmp(request_info->uri, "/dd.xml") &&
        !strcmp(request_info->request_method, "GET")) {
      mg_printf(conn, "HTTP/1.1 200 OK\r\n"
                      "Content-Type: application/xml\r\n"
                      "Application-URL: http://%s:%d/apps/\r\n"
                      "\r\n", ip_addr, dial_port);
      mg_printf(conn, ddxml, friendly_name, model_name, uuid);
    } else {
      mg_send_http_error(conn, 404, "Not Found", "Not Found");
    }
    return "done";
  }
  return NULL;
}

static void get_local_address() {
  struct ifconf ifc;
  char buf[4096];
  int s, i;
  if (-1 == (s = socket(AF_INET, SOCK_DGRAM, 0))) {
    perror("socket");
    exit(1);
  }
  ifc.ifc_len = sizeof(buf);
  ifc.ifc_buf = buf;
  if (0 > ioctl(s, SIOCGIFCONF, &ifc)) {
    perror("SIOCGIFCONF");
    exit(1);
  }
  if (ifc.ifc_len == sizeof(buf)) {
    fprintf(stderr, "SIOCGIFCONF output too long");
    exit(1);
  }
  close(s);
  for (i = 0; i < ifc.ifc_len/sizeof(ifc.ifc_req[0]); i++) {
    strcpy(ip_addr,
      inet_ntoa(((struct sockaddr_in *)(&ifc.ifc_req[i].ifr_addr))->sin_addr));
    // exit if we found a non-loopback address
    if (strcmp("127.0.0.1", ip_addr)) {
      break;
    }
  }
}

static void handle_mcast() {
  int s, one = 1, bytes;
  socklen_t addrlen;
  struct sockaddr_in saddr;
  struct ip_mreq mreq;
  char send_buf[sizeof(ssdp_reply) + INET_ADDRSTRLEN + 256 + 256] = {0,};
  int send_size;

  send_size = snprintf(send_buf, sizeof(send_buf), ssdp_reply, ip_addr, my_port, uuid);

  if (-1 == (s = socket(AF_INET, SOCK_DGRAM, 0))) {
    perror("socket");
    exit(1);
  }
  if (-1 == setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) {
    perror("reuseaddr");
    exit(1);
  }
  saddr.sin_family = AF_INET;
  saddr.sin_addr.s_addr = inet_addr("239.255.255.250");
  saddr.sin_port = htons(1900);
  if (-1 == bind(s, (struct sockaddr *)&saddr, sizeof(saddr))) {
    perror("bind");
    exit(1);
  }
  mreq.imr_multiaddr.s_addr = inet_addr("239.255.255.250");
  mreq.imr_interface.s_addr = inet_addr(ip_addr);
  if (-1 == setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,
                       &mreq, sizeof(mreq))) {
    perror("add_membership");
    exit(1);
  }
  //printf("Starting Multicast handling on 239.255.255.250\n");
  while (1) {
    addrlen = sizeof(saddr);
    if (-1 == (bytes = recvfrom(s, gBuf, sizeof(gBuf) - 1, 0,
                                (struct sockaddr *)&saddr, &addrlen))) {
      perror("recvfrom");
      continue;
    }
    gBuf[bytes] = 0;

    // sophisticated SSDP parsing algorithm
    if (!strstr(gBuf, "urn:dial-multiscreen-org:service:dial:1") &&
        !strstr(gBuf, "ST: urn:dial-multiscreen-org:device:dial:1"))
    {
#if 0  // use for debugging
      fprintf(stderr, "Dropping: \n");
      {
          int i;
          for (i = 0; i < bytes; i++)
          {
              putchar(gBuf[i]);
          }
      }
      fprintf(stderr, "\n##### End of DROP #######\n");
#endif
      continue;
    }
    if (dial_allowed()) {
        fprintf(stderr, "Sending SSDP reply to %s:%d\n",
              inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
        if (-1 == sendto(s, send_buf, send_size, 0, (struct sockaddr *)&saddr, addrlen)) {
          perror("sendto");
          continue;
        }
    }
  }
}

void run_ssdp(int port, const char *pFriendlyName, const char * pModelName, const char *pUuid, const char **ppIpAddress) {
  struct sockaddr sa;
  socklen_t len = sizeof(sa);

  if(pFriendlyName) {
      strncpy(friendly_name, pFriendlyName, sizeof(friendly_name));
      friendly_name[255] = '\0';
  } else {
      strcpy(friendly_name, "DIAL server sample");
  }
  if(pModelName) {
      strncpy(model_name, pModelName, sizeof(model_name));
      model_name[255] = '\0';
  } else {
      strcpy(model_name, "deadbeef-dead-beef-dead-beefdeadbeef");
  }
  if(pUuid) {
      strncpy(uuid, pUuid, sizeof(uuid));
      uuid[255] = '\0';
  } else {
      strcpy(uuid, "deadbeef-dead-beef-dead-beefdeadbeef");
  }

  dial_port = port;
  get_local_address();
  *ppIpAddress = ip_addr;
  ctx = mg_start(&request_handler, NULL, SSDP_PORT);

  if (mg_get_listen_addr(ctx, &sa, &len)) {
    my_port = ntohs(((struct sockaddr_in *)&sa)->sin_port);
  }

  fprintf(stderr, "SSDP listening on %s:%d\n", ip_addr, my_port);
  handle_mcast();
}
