// 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;
  struct device_list *devices;

  sage_log((_LOG_TRACE, 3, "hdhr:hdhomerun device init"));

  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++ ) {
      devices->hdhrs[i].tuner_id = index++;
      snprintf(devices->hdhrs[i].tuner_name,
               sizeof(devices->hdhrs[i].tuner_name), "%s-%s",
               devices->hdhrs[i].model, 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->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;
  }

  if ( hdhr->cc_tuner ) {
    /* HDHomeRun PRIME */
    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 US */
    char tune_str[32], map_str[32], prog_str[8];
    int ch = -1, prog = -1, vch_major = -1, vch_minor = -1;
    char *ps, *pe;
    map_str[0] = 0x0;

    /*
     * channel format: xx-yy-zz
     * xx=physical channel, yy=virtual major channel, zz=virtual minor channel
     */
    if (sscanf(channel, "%d-%d-%d", &ch, &vch_major, &vch_minor) == 3) {
      ret = tune_vchannel(hdhr->hd, ch, vch_major, vch_minor, stream_tar);
      goto out;
    }

    /*
     * channel format: xx-yy
     * xx=physical channel, yy=virtual major channel
     */
    if (sscanf(channel, "%d-%d", &ch, &vch_major) == 2) {
      vch_minor = 0;
      ret = tune_vchannel(hdhr->hd, ch, vch_major, vch_minor, stream_tar);
      goto out;
    }

    //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 ) {
        snprintf( map_str, sizeof(map_str), "map:us-bcast" );
      }
    }
    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;
    }
  }

out:
  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 {
    sage_log((_LOG_TRACE, 3, "hdhr:hdhomerun ATSC dev_scan not implemented %s.",
              (char*)hdhr->name));
  }

  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 {
    sage_log((_LOG_TRACE, 3, "hdhr:hdhomerun ATSC build_hdhr_channel_table not implemented %s.",
              (char*)hdhr->name));
  }
  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;
}


