// Copyright 2011 Google Inc. All Rights Reserved.
// Author: qianzhang@google.com (Qian Zhang)

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <inttypes.h>
#include <assert.h>
#include "utility.h"
#include "hdhomerun_plugin.h"
#include "libhdhomerun/hdhomerun.h"
#include "hdhomerun_tuner.h"
#include "hdhomerun_dev.h"
#include "hdhomerun_tuner.h"
#include "channel_buffer.h"
#include "sagelog.h"

#define MAX_TUNER_NUM 16

struct device_list {
  int tuner_num;
  int list_num;
  struct hdhr_tuner_t *hdhrs;
};

static int discover_hdhrs( struct hdhr_tuner_t *ht, int max_ht_num )
{
  int  i, ret = 0 ;
  ret = discover_device( ht, max_ht_num );
  if ( ret > 0 ) {
    for ( i = 0; i<ret; i++ ) {
      //if a unit shares a source input in a device, copy data.
      if ( i> 0 && tuner_input_sharing( &ht[i-1], &ht[i] ) ) {
        ht[i].cc_tuner = ht[i-1].cc_tuner;
        strncpy( ht[i].model, ht[i-1].model, sizeof(ht[i].model) );
      } else
        get_dev_model( &ht[i] );
    }
    return i;
  }
  return 0;
}

void* dev_init( int *num )
{
  int i, index = 0, tuner_num;
  char *type_name[2] ={ "NR", "CC" };
  sage_log(( _LOG_TRACE, 3,  "hdhr::hdhomerun device init" ));
  struct device_list *devices = (struct device_list *)malloc( sizeof(struct device_list) );
  if ( devices != NULL ) {
    devices->hdhrs = (struct hdhr_tuner_t *)malloc(sizeof(struct hdhr_tuner_t) * MAX_TUNER_NUM );
    memset( devices->hdhrs, 0, sizeof(sizeof(struct hdhr_tuner_t) * MAX_TUNER_NUM) );
    if ( devices->hdhrs == NULL ) {
      free( devices);
      return 0;
    }
    devices->list_num = MAX_TUNER_NUM;
    devices->tuner_num = 0;
    tuner_num = discover_hdhrs( devices->hdhrs, MAX_TUNER_NUM );
    for ( i = 0; i<tuner_num; i++ ) {
      int type = 0;
      devices->hdhrs[i].tuner_id = index++;
      if ( devices->hdhrs[i].cc_tuner )
        type = 1;
      else
        type = 0;
      snprintf( devices->hdhrs[i].tuner_name, sizeof(devices->hdhrs[i].tuner_name), "HDHR-%s-%s", type_name[type], devices->hdhrs[i].name );
      devices->tuner_num++;
      sage_log(( _LOG_TRACE, 3, "hdhr:%d %s %s %s", i, devices->hdhrs[i].tuner_name, devices->hdhrs[i].model, devices->hdhrs[i].cc_tuner?"CableCard":"" ));
    }
    devices->tuner_num = tuner_num;
    *num = tuner_num;
    return devices;
  }
  return NULL;
}

void dev_release( void* handle )
{
  struct device_list *devices = (struct device_list *)handle;
  if ( devices != NULL ) {
    if ( devices->hdhrs != NULL )
      free( devices->hdhrs );
    free( devices );
  }
  sage_log(( _LOG_TRACE, 3,  "hdhr:hdhomerun device release." ));
}

int get_dev_name( void* handle, int index, char* name, int max_name_len  )
{
  struct device_list *devices = (struct device_list *)handle;
  if ( devices != NULL && index < devices->tuner_num ) {
    struct hdhr_tuner_t* hdhr = &devices->hdhrs[index];
    strncpy( name, hdhr->tuner_name, max_name_len );
    return 1;
  }
  return 0;
}

void* dev_open( void* handle, int index, int attr )
{
  struct device_list *devices = (struct device_list *)handle;
  struct hdhr_tuner_t* hdhr;
  if ( index >= devices->tuner_num )
    return NULL;
  hdhr = &devices->hdhrs[index];
  hdhr->type = attr; //1:atsc 2:qam
  hdhr->hd = open_hdhr( hdhr->name );
  return hdhr;
}

void dev_close( void* dev )
{
  struct hdhr_tuner_t* hdhr = (struct hdhr_tuner_t*)dev;
  if ( hdhr == NULL ) {
    sage_log(( _LOG_TRACE, 3, "hdhr:ERROR: invalid device handle." ));
    return;
  }
  stop_channel( hdhr->hd );
  close_hdhr( hdhr->hd );
}

int dev_tune( void* dev, char* channel, char* stream_tar )
{
  int ret;
  struct hdhr_tuner_t* hdhr = (struct hdhr_tuner_t*)dev;
  if ( hdhr == NULL ) {
    sage_log(( _LOG_TRACE, 3, "hdhr:ERROR: invalid device handle." ));
    return 0;
  }
  sage_log(( _LOG_TRACE, 3, "hdhr:hdhomerun tune %s %s.", hdhr->name, (char*)channel ));
  if ( strstr( stream_tar, "udp://" ) == NULL ) {
    sage_log(( _LOG_TRACE, 3, "hdhr:ERROR: stream target \"%s\" is wrong.", stream_tar ));
    return 0;
  }
  //cablecard tuner:HDHomerun prime unit
  if ( hdhr->cc_tuner ) {
    if ( strstr( channel, "vchan:" ) == NULL ) {
      char vchan[32];
      snprintf( vchan, sizeof(vchan), "vchan:%d", atoi(channel) );
      ret = tune_channel( hdhr->hd, vchan, "", stream_tar );
    } else
      ret = tune_channel( hdhr->hd, channel, "", stream_tar );
  } else {
    //HDHomeRun unit
    char tune_str[32], map_str[8], prog_str[8];
    int ch = -1, prog = -1;
    char *ps, *pe;
    map_str[0] = 0x0;
    //if channel in format "map:xxx-yy|auto:zzz prog:ppp"
    if ( ( ps = strstr( channel, "map:" ))!= NULL &&
       ( pe = strchr( ps+4, '|' )) != NULL ) {
      strncpy( map_str, ps+4, pe-(ps+4) );
      map_str[pe-(ps+4)] = 0x0;
    }
    get_int_val_by_name( channel, "auto", &ch, NULL );
    get_int_val_by_name( channel, "prog", &prog, NULL );
    if ( prog == -1 ) {
      sage_log(( _LOG_TRACE, 3, "hdhr:ERROR: invalid channel string %s", channel ));
      return 0;
    }
    //if channel in format "nnn prog:mmm", based on dev to guess map
    if ( map_str[0] == 0x0 && prog > 0 && ch == -1 ) {
      ch=atoi( channel );
      if ( ch > 0 ) {
        int atsc = ( hdhr->type == 1 ); //TODO dvb
        snprintf( map_str, sizeof( map_str), "map:us-%s", atsc? "atsc":"cable" );
      }
    }
    if ( map_str[0] && ch > 0 && prog > 0 ) {
      snprintf( tune_str, sizeof(tune_str), "%s|auto:%d", map_str, ch );
      snprintf( prog_str, sizeof(prog), "%d", prog );
      ret = tune_channel( hdhr->hd, tune_str, prog_str, stream_tar );
    } else {
      sage_log(( _LOG_ERROR, 3, "hdhr:ERROR: invalid channel string %s", channel ));
      return 0;
    }
  }
  sage_log(( _LOG_TRACE, 3, "hdhr:hdhomerun tune %s %s.", (char*)channel, ret>0?"successful":"failed" ));
  return ret > 0;
}

int dev_stop( void* dev )
{
  struct hdhr_tuner_t* hdhr = (struct hdhr_tuner_t*)dev;
  if ( hdhr == NULL ) {
     sage_log(( _LOG_TRACE, 3, "hdhr:ERROR: invalid device handle." ));
    return 0;
  }
  sage_log(( _LOG_TRACE, 3, "hdhr:hdhomerun stop %s.", (char*)hdhr->name ));
  int ret = stop_channel( hdhr->hd );
  return ret > 0;
}

int dev_scan( void* dev, char* tuner_name, char* channel, struct channel_list_t **cl_p )
{
  struct hdhr_tuner_t* hdhr = (struct hdhr_tuner_t*)dev;
  if ( hdhr == NULL ) {
    sage_log(( _LOG_TRACE, 3, "hdhr:ERROR: invalid device handle." ));
    return 0;
  }
  sage_log(( _LOG_TRACE, 3, "hdhr:hdhomerun scan %s.", (char*)hdhr->name ));
  if ( hdhr->cc_tuner ) {
    int vchannel;
    char *p;
    if ( ( p = strstr( channel, "vchan:" ) ) == NULL )
      vchannel = atoi(channel) ;
    else
      vchannel = atoi(p+6);
    if ( vchannel == 0 )
      return 0;

    struct channel_list_t *cl = _create_channel_list( 1 );
    int ret = scan_vchannel( hdhr->hd, vchannel, cl->ce );
    char unit_name[16];
    snprintf( cl->ce[0].dev_name, sizeof(cl->ce[0].dev_name)-1, "HDHR.%s", get_unit_name( hdhr, unit_name, sizeof(unit_name) ));
    cl->channel_num = ret;
    if ( ret == 0 ) {
      _release_channel_list( cl );
      cl = NULL;
    }
    if ( cl_p != NULL )
      *cl_p = cl;
    return ret;
  } else {
    //TODO
  }

  return 0;
}

static struct channel_list_t * build_hdhr_channel_table(  struct hdhr_tuner_t* hdhr )
{
  if ( hdhr->cc_tuner ) {
    struct vchan_tbl_t* vt = create_vchan_tbl( hdhr );
    struct channel_list_t *cl = NULL;
    if ( get_vchannel_list( vt ) > 0 ) {
      int num = vt->channel_num;
      cl = _create_channel_list( num );
      int i;
      for ( i = 0; i<num; i++ ) {
        char unit_name[16];
        cl->ce[i].state = 1;
        snprintf( cl->ce[i].dev_tuning, sizeof(cl->ce[i].dev_tuning)-1, "vchan:%d", vt->vchan[i].guide_id );
        snprintf( cl->ce[i].ch_name, sizeof(cl->ce[i].ch_name)-1, "%d", vt->vchan[i].guide_id );
        strncpy( cl->ce[i].ch_desc, vt->vchan[i].guide_name, sizeof(cl->ce[i].ch_desc)-1 );
        cl->ce[i].src_ip[0] = 0x0;
        cl->ce[i].src_port = 0;    //dynamic assigning
        snprintf( cl->ce[i].dev_name, sizeof(cl->ce[i].dev_name)-1, "HDHR.%s", get_unit_name( hdhr, unit_name, sizeof(unit_name) ));
        cl->ce[i].ch = vt->vchan[i].guide_id;
        cl->ce[i].frq = 0;
        cl->ce[i].av_inf[0] = 0;
      }
      cl->channel_num = i;
    }
    release_vchan_tbl( vt );
    return cl;
  } else { //TODO

  }
  return NULL;
}

int dev_build_channel_table( void* dev, char* option, struct channel_list_t **cl_p )
{
  struct hdhr_tuner_t* hdhr = (struct hdhr_tuner_t*)dev;
  if ( hdhr == NULL ) {
    sage_log(( _LOG_TRACE, 3, "hdhr:ERROR: invalid device handle." ));
    return 0;
  }
  sage_log(( _LOG_TRACE, 3, "hdhr:hdhomerun dev_build_channel_table %s.", (char*)hdhr->name ));
  struct channel_list_t *cl= build_hdhr_channel_table( hdhr );
  if ( cl_p != NULL ) {
    *cl_p = cl;
    if ( cl == NULL )
      return 0;
    return cl->channel_num;
  }
  return 0;
}

int dev_release_channel_table( void* dev )
{
  struct hdhr_tuner_t* hdhr = (struct hdhr_tuner_t*)dev;
  if ( hdhr == NULL ) {
    sage_log(( _LOG_TRACE, 3, "hdhr:ERROR: invalid device handle." ));
    return 0;
  }
  sage_log(( _LOG_TRACE, 3, "hdhr:hdhomerun dev_release_channel_table %s.", (char*)hdhr->name ));
  if ( hdhr->channel_table != NULL ) {
    free( hdhr->channel_table );
    hdhr->channel_table = NULL;
    return 1;
  } else {  //TODO

  }
  return 0;
}


