/*****************************************************************
 * gmerlin - a general purpose multimedia framework and applications
 *
 * Copyright (c) 2001 - 2012 Members of the Gmerlin project
 * gmerlin-general@lists.sourceforge.net
 * http://gmerlin.sourceforge.net
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * *****************************************************************/

#include <string.h>


#include "server.h"

#include <gmerlin/http.h>
#include <gmerlin/utils.h>
#include <gmerlin/bggavl.h>

#include <gavl/metatags.h>

static int handle_internal(bg_http_connection_t * conn, void * data, int xml)
  {
  char * str = NULL;
  int len;
  int ret;
  gavl_value_t val;
  int have_val;
  
  char * tmp_string;
  char * pos;
  
  server_t * s = data;

  gavl_value_init(&val);
  have_val = 0;
  
  if(strcmp(conn->method, "GET") && strcmp(conn->method, "HEAD"))
    {
    bg_http_connection_init_res(conn, "HTTP/1.1", 
                                405, "Method Not Allowed");
    goto go_on;
    }

  
  if(!strcmp(conn->path, "devices"))
    {
    gavl_value_t dev;
    gavl_array_t * arr;
    gavl_dictionary_t * dict;
    
    char dev_id[BG_REMOTE_DEVICE_ID_LEN+1];
    int i = 0;
    bg_remote_device_info_t * info =
      bg_remote_device_registry_get(s->remote_reg);

    arr = gavl_value_set_array(&val);
    
    
    while(info[i].label)
      {
      gavl_value_init(&dev);
      dict = gavl_value_set_dictionary(&dev);

      gavl_dictionary_set_string(dict, GAVL_META_LABEL, info[i].label);
      if(info[i].protocol)
        gavl_dictionary_set_string(dict, "protocol", info[i].protocol);

      if(info[i].url)
        {
        gavl_dictionary_set_string(dict, GAVL_META_URI, info[i].url);

        /* Append proxy URL */
        if(strcmp(info[i].protocol, "gmerlin"))
          {
          bg_remote_device_info_get_id(&info[i], dev_id);
          pos = strstr(s->root_url, "://");
          tmp_string = bg_sprintf("ws%s%s%s", pos, BG_REMOTE_DEVICE_PATH, dev_id);
          gavl_dictionary_set_string(dict, "proxy", tmp_string);
          free(tmp_string);
          }
        }
            
      if(info[i].icon)
        gavl_dictionary_set_string(dict, GAVL_META_ICON, info[i].icon);

      gavl_dictionary_set_string(dict, "type", bg_remote_device_type_to_label(info[i].type));
      gavl_array_push_nocopy(arr, &dev);
      i++;
      }
    have_val = 1;
    }
  else if(!strcmp(conn->path, "mimetypes"))
    {
    gavl_value_t type;
    gavl_array_t * arr;
    gavl_dictionary_t * dict;
    int i = 0;
    
    arr = gavl_value_set_array(&val);
    
    while(bg_mimetypes[i].name)
      {
      gavl_value_init(&type);
      dict = gavl_value_set_dictionary(&type);

      gavl_dictionary_set_string(dict, GAVL_META_LABEL, bg_mimetypes[i].name);
      gavl_dictionary_set_string(dict, GAVL_META_MIMETYPE, bg_mimetypes[i].mimetype);
      gavl_dictionary_set_string(dict, "ext", bg_mimetypes[i].ext);
      
      i++;

      gavl_array_push_nocopy(arr, &type);
      }
    have_val = 1;
    }

  bg_http_connection_check_keepalive(conn);
  
  if(!have_val) // 404
    return 0;

  bg_http_connection_init_res(conn, "HTTP/1.1", 200, "OK");

  if(xml)
    {
    xmlDocPtr xml_doc = NULL;
    xmlNodePtr root;
    xml_doc = xmlNewDoc((xmlChar*)"1.0");
    root = xmlNewDocRawNode(xml_doc, NULL, (xmlChar*)"devices", NULL);
    xmlDocSetRootElement(xml_doc, root);
    bg_value_2_xml(root, &val);
    str = bg_xml_save_to_memory(xml_doc);
    len = strlen(str);
    gavl_dictionary_set_string(&conn->res, "Content-Type", "text/xml; charset=\"utf-8\"");
    if(xml_doc)
      xmlFreeDoc(xml_doc);
    }
  else
    {
    struct json_object * json = bg_value_to_json(&val);
    str = gavl_strdup(json_object_to_json_string_ext(json, 0));
    len = strlen(str);
    if(json)
      json_object_put(json);
    gavl_dictionary_set_string(&conn->res, "Content-Type", "application/json");
    }
  
  gavl_dictionary_set_long(&conn->res, "Content-Length", len);
  ret = 1;

  go_on:
  
  if(!bg_http_server_write_res(s->s, conn) ||
     !bg_socket_write_data(conn->fd, (const uint8_t*)str, len))
    goto fail;
  
  fail:
  
  if(str)
    free(str);

  gavl_value_free(&val);
  
  return ret;
  }

int handle_xml(bg_http_connection_t * conn, void * data)
  {
  return handle_internal(conn, data, 1);
  }

int handle_json(bg_http_connection_t * conn, void * data)
  {
  return handle_internal(conn, data, 0);
  }
  
