
#include <stdio.h>
 #include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include <inttypes.h>
#include "utility.h"
#include "hdhomerun_tuner.h"
#include "hdhomerun_http.h"
#include "hdhomerun_dev.h"
#include "sagelog.h"

#define _MIN_(x,y) ((x)>(y)? (y):(x))

static int read_elemnt( char* xml, char* tag, char* buf, int size )
{
  char open_tag[256], close_tag[256];
  char *start, *end;
  snprintf( open_tag, sizeof(open_tag), "<%s>", tag );
  snprintf( close_tag, sizeof(open_tag), "</%s>", tag );

  start = strstr( xml, open_tag );
  if ( start != NULL ) {
    start += strlen( open_tag );
    end = strstr( start, close_tag );
    if ( end != NULL ) {
      int len = _MIN_( end - start, size );
      memcpy( buf, start, len );
      buf[len] = 0;
      end += strlen( close_tag );
      return end - xml;
    }
  }
  return 0;
}

static void html_txt_converison( char* txt )
{
  char *p;
  do {
    //remove &amp;
    p = strstr( txt, "&amp;" );
    if ( p ) 
      strcpy( p+1, p+1+4 );
  }  while ( p );
}

//remove tag and trim space
static void cleanup_txt( char* txt )
{
  int n = strlen( txt );
  while ( n > 0 ) {
    if ( txt[n] == ' ' || txt[n] == '<' || txt[n] == '\r' || txt[n] == '\n' )
      txt[n] = 0x0;
    n--;
  }
}

static int program_parser( void* context, char* buf, int bytes )
{
  struct vchan_tbl_t *vt = (struct vchan_tbl_t*)context;
  int pos, used_bytes;
  char guide_num[16], guide_name[64];;
  pos = 0;
  while ( pos < bytes ) {
    used_bytes = read_elemnt( buf+pos, "GuideNumber", guide_num, sizeof(guide_num) );
    if ( used_bytes == 0 )
      break;
    pos += used_bytes;
    //printf( "%s ", guide_num );
    used_bytes = read_elemnt( buf+pos, "GuideName", guide_name, sizeof(guide_name) );
    if ( used_bytes == 0 )
      break;
    html_txt_converison( guide_name );
    if ( vt->channel_num >= vt->channel_size )
      grow_vhcan_tbl( vt );
    if ( vt->channel_num < vt->channel_size ) {
      int i = vt->channel_num;
      vt->vchan[i].guide_id = atoi( guide_num );
      snprintf( vt->vchan[i].guide_name, sizeof(vt->vchan[i].guide_name), "\"%s\"", guide_name );
      vt->channel_num++;
    }  
    pos += used_bytes;
    //printf( "%s;\n", guide_name );
  }
  return pos;
}

static int hdhomerun_parser( void* context, char* buf, int bytes )
{
  char *p;
  struct hdhr_tuner_t *ht = (struct hdhr_tuner_t *)context; 
  p = strstr( buf, "Model:" );
  if ( p != NULL ) {
    if ( strlen( p+6 )<10 )
      return p-buf;
    if ( get_string_by_name( p, "Model", ht->model, sizeof(ht->model), NULL ) ) {
      cleanup_txt( ht->model );
    }
  }
  
  if ( strstr( buf, "CableCARD Menu" ) != NULL ) {
    ht->cc_tuner = 1;
  } 
  return bytes;
}

int get_dev_model( struct hdhr_tuner_t *ht )
{
  int ret = parse_http_page( ht->ip, "/", hdhomerun_parser, ht );
  return ret;
}

int get_vchannel_list( struct vchan_tbl_t *vt )
{
  int ret = parse_http_page( vt->ht.ip, "/lineup.xml", program_parser, vt );
  return ret;
}

  //parse_http_page( "192.168.1.168", "/", hdhomerun_parser, NULL );
  //parse_http_page( "192.168.1.168", "/lineup.xml", program_parser, NULL );

