// 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 "utility.h"
#include "channel_buffer.h"
#include "libhdhomerun/hdhomerun.h"
#include "hdhomerun_tuner.h"
#include "hdhomerun_dev.h"
#include "sagelog.h"

#define PARSE_TIMEOUT 2
#define CHANNE_SCAN_SRC   "227.0.0.1"
#define CHANNEL_SCAN_PORT  6069
static volatile sig_atomic_t sigabort_flag = FALSE;
static volatile sig_atomic_t siginfo_flag = FALSE;
static const char* map_tbl[] ={ "us-bcast", "us-cable", "us-hrc", "us-irc", "au-bcast", "tw-bcast", "eu-bcast", 0x0 };

static void sigabort_handler(int arg)
{
  sigabort_flag = TRUE;
}

static void siginfo_handler(int arg)
{
  siginfo_flag = TRUE;
}

static void register_signal_handlers(sig_t sigpipe_handler, sig_t sigint_handler, sig_t siginfo_handler)
{
#if defined(SIGPIPE)
  signal(SIGPIPE, sigpipe_handler);
#endif
#if defined(SIGINT)
  signal(SIGINT, sigint_handler);
#endif
#if defined(SIGINFO)
  signal(SIGINFO, siginfo_handler);
#endif
}

//channel format: map:us-cable,auto:68
void* open_hdhr( char* name )
{
  struct hdhomerun_device_t *hd;
  hd = hdhomerun_device_create_from_str( name, NULL);
  return hd;
}
void close_hdhr( void* device )
{
  struct hdhomerun_device_t *hd =(struct hdhomerun_device_t *)device;
  if ( hd ) {
    hdhomerun_device_stream_stop( hd );
    hdhomerun_device_destroy( hd );
  }
}

int tune_channel( void* device, char *channel, char *program, char* stream_target )
{
  char channel_str[32]="auto:";
  char vchannel_str[16];
  char channel_map[32];
  struct hdhomerun_device_t *hd =(struct hdhomerun_device_t *)device;
  struct hdhomerun_channel_list_t *channel_list=NULL;
  int ret;

  if ( hd == NULL ) {
    printf( "hdhomerun invalid handle\n");
    return -1;
  }

  if ( !get_string_by_name( channel, "vchan", vchannel_str, sizeof(vchannel_str), NULL ) ) {
    vchannel_str[0] = 0x0;

    if ( !get_string_by_name( channel, "auto", channel_str+5, sizeof(channel_str)-5, NULL ) ) {
      printf("hdhomerun %p invalid channel %s\n", device, channel );
      return -1;
    }
    if ( !get_string_by_name( channel, "map", channel_map, sizeof(channel_map), NULL ) ) {
      printf("hdhomerun %p invalid channel map %s\n", device, channel );
      strncpy( channel_map, "us-cable", sizeof(channel_map) );
    }
    if ( program[0] == 0x0 ) {
      printf("hdhomerun %p invalid channel program %s\n", device, program );
      return -1;
    }
    channel_list = hdhomerun_channel_list_create( channel_map );
    if ( channel_list == NULL ) {
      printf( "hdhomerun failed to create channel map\n");
      return -1;
    }
    ret = hdhomerun_device_set_tuner_channelmap( hd, channel_map );
    if ( ret < 0 )
      printf( "hdhomerun failed to set tuner channel map %s\n", channel_map );

    ret = hdhomerun_device_set_tuner_channel( hd, channel_str );
    if ( ret < 0 )
      printf("hdhomerun tuning failed:%s ret:%d\n", channel_str, ret );

    ret = hdhomerun_device_set_tuner_program( hd, program );
    if ( ret <= 0 )
      printf( "hdhomerun failed set program:%s ret:%d\n", program, ret );
  } else {
    ret = hdhomerun_device_set_tuner_vchannel( hd, vchannel_str );
    if ( ret < 0 )
      printf("hdhomerun tuning failed: vchannel:%s ret:%d\n", vchannel_str, ret );
  }

  char target[64];
  snprintf( target, sizeof(target), "%s ttl-16",stream_target );
  ret = hdhomerun_device_set_tuner_target( hd, target );
  if ( ret < 0 ) {
    printf( "hdhomerun failed set target %s  ret:%d\n", target, ret );
  }
  if ( channel_list )
    hdhomerun_channel_list_destroy( channel_list );

  return ret;
}

//channel format: map:us-cable,auto:68
int stop_channel( void* device )
{
  int ret;
  struct hdhomerun_device_t *hd =(struct hdhomerun_device_t *)device;
  if ( hd == NULL ) {
    printf( "hdhomerun invalid handle\n");
    return -1;
  }

  ret = hdhomerun_device_set_tuner_channel( hd, "none" );
  if ( ret < 0 ) {
    printf( "hdhomerun failed set channel none to stop streaming  ret:%d\n", ret );
  }

  ret = hdhomerun_device_set_tuner_vchannel( hd, "none" );
  if ( ret < 0 ) {
    printf( "hdhomerun failed set vchannel none to stop streaming  ret:%d\n", ret );
  }

  ret = hdhomerun_device_set_tuner_target( hd, "none" );
  if ( ret < 0 ) {
    printf( "hdhomerun failed set target none to stop streaming  ret:%d\n", ret );
  }

  return ret;
}

char* get_unit_name( struct hdhr_tuner_t *ht, char* name, int size )
{
  char* p = strchr( ht->name, '-' );
  if ( p != NULL ) {
    int len = p - ht->name;
    strncpy( name, ht->name, len );
    name[len] = 0x0;
    return name;
  }
  name[ 0 ] = 0x0;
  return name;
}

static char* ip4_address( int ip4, char *buf, int size )
{
  snprintf( buf, size, "%u.%u.%u.%u",
    (unsigned int)(ip4 >> 24) & 0xFF, (unsigned int)(ip4 >> 16) & 0xFF,
    (unsigned int)(ip4 >> 8) & 0xFF, (unsigned int)(ip4 >> 0) & 0xFF  );
  return buf;
}

int discover_device( struct hdhr_tuner_t *ht, int max_ht_num )
{
  int i, k, num = 0;
  struct hdhomerun_discover_device_t *device_info = malloc( max_ht_num * sizeof(struct hdhomerun_discover_device_t) );
  int ret = hdhomerun_discover_find_devices_custom(0, HDHOMERUN_DEVICE_TYPE_TUNER, -1, device_info, 16);
  if ( ret <= 0 ) {
    free( device_info );
    return 0;
  }
  //printf( "found %d hdhomerun device\n", ret );
  for ( i = 0; i<ret; i++ ) {
    //printf( "ip:%x type:%x id:%x num:%d\n", device_info[i].ip_addr, device_info[i].device_type, device_info[i].device_id,
    //    device_info[i].tuner_count );
    for ( k = 0; k<device_info[i].tuner_count && num < max_ht_num; k++ ) {
      snprintf( ht[num].name, sizeof(ht[num].name), "%X-%d", device_info[i].device_id, k );
      ip4_address( device_info[i].ip_addr, ht[num].ip, sizeof(ht[num].ip) );
      ht[num].type = device_info[i].device_type;
      ht[num].cc_tuner = 0;
      ht[num].model[0] = 0;
      num++;
    }
  }
  free( device_info );
  return num;
}

static char *get_tune_string( char* result, char* tune_str, int tune_str_len )
{
  int i = 0;
  int ch;
  while ( map_tbl[i][0] ) {
    if ( get_int_val_by_name( result, map_tbl[i], &ch, NULL ) > 0 ) {
      snprintf( tune_str, tune_str_len, "map:%s|auto:%d", map_tbl[i], ch );
      return tune_str;
    }
    i++;
  }
  return "";
}

static int get_tune_channel( char* result )
{
  int i = 0;
  int ch;
  while ( map_tbl[i][0] ) {
    if ( get_int_val_by_name( result, map_tbl[i], &ch, NULL ) > 0 ) {
      return ch;
    }
    i++;
  }
  return 0;
}

int scan_all( void* device, struct channel_entry_t *ce, int ce_num )
{
  int found_channel = 0;
  struct hdhomerun_device_t *hd =(struct hdhomerun_device_t *)device;
  if ( hd == NULL ) {
    printf( "hdhomerun invalid handle\n");
    return -1;
  }

  char *ret_error;
  if (hdhomerun_device_tuner_lockkey_request(hd, &ret_error) <= 0) {
    fprintf(stderr, "failed to lock tuner\n");
    if (ret_error) {
      fprintf(stderr, "%s\n", ret_error);
    }
    return -1;
  }

  hdhomerun_device_set_tuner_target(hd, "none");

  char *channelmap;
  if (hdhomerun_device_get_tuner_channelmap(hd, &channelmap) <= 0) {
    fprintf(stderr, "failed to query channelmap from device\n");
    return -1;
  }

  const char *channelmap_scan_group = hdhomerun_channelmap_get_channelmap_scan_group(channelmap);
  if (!channelmap_scan_group) {
    fprintf(stderr, "unknown channelmap '%s'\n", channelmap);
    return -1;
  }

  if (hdhomerun_device_channelscan_init(hd, channelmap_scan_group) <= 0) {
    fprintf(stderr, "failed to initialize channel scan\n");
    return -1;
  }

  register_signal_handlers(sigabort_handler, sigabort_handler, siginfo_handler);

  int ret = 0;
  while (!sigabort_flag && found_channel < ce_num ) {
    struct hdhomerun_channelscan_result_t result;
    char tune_str[32];
    char channel_name[32];
    int channel_num;
    ret = hdhomerun_device_channelscan_advance( hd, &result );
    if (ret <= 0) {
      break;
    }

    ret = hdhomerun_device_channelscan_detect( hd, &result );
    if (ret < 0) {
      break;
    }
    if (ret == 0) {
      continue;
    }
    if ( 0 )
    printf("LOCK: %s %s (ss=%u snq=%u seq=%u)\n", get_tune_string( result.channel_str, tune_str, sizeof(tune_str)),
      result.status.lock_str, result.status.signal_strength,
      result.status.signal_to_noise_quality, result.status.symbol_error_quality
    );

    channel_num = get_tune_channel( result.channel_str );
    int i;
    for (i = 0; i < result.program_count; i++) {
      struct hdhomerun_channelscan_program_t *program = &result.programs[i];
      if ( strstr( program->program_str, "encrypted" ) == NULL ) {
        int program_id = atoi( program->program_str );

        if ( !get_string_by_token( program->program_str, 2, channel_name, sizeof(channel_name), NULL ) ) {
          if ( !get_string_by_token( program->program_str, 1, channel_name, sizeof(channel_name), NULL ) )
            snprintf( channel_name, sizeof(channel_name), "%d.%d", channel_num, i );
          else {
            if ( !strcmp(channel_name, "0" ) )
              snprintf( channel_name, sizeof(channel_name), "%d.%d", channel_num, i );
          }
        }
        snprintf( ce->dev_tuning, sizeof(ce->dev_tuning), "%s prog:%d", get_tune_string( result.channel_str, tune_str, sizeof(tune_str) ),
                 program_id );
        strncpy( ce->ch_name, channel_name, sizeof(ce->ch_name) );
        strncpy( ce->dev_name, device, sizeof(ce->dev_name) );
        ce->ch = found_channel;
        ce->frq = result.frequency;
        ce->av_inf[0] = 0x0;
        ce++;
        if ( ++found_channel >= ce_num )
          break;

        printf("o");
      }
    }

    printf( "." ); fflush( stdout );
  }

  hdhomerun_device_tuner_lockkey_release(hd);

  if (ret < 0) {
    fprintf(stderr, "communication error sending request to hdhomerun device\n");
  }
  return found_channel;
}


struct vchan_tbl_t* create_vchan_tbl( struct hdhr_tuner_t *ht )
{
  struct vchan_tbl_t *vt = malloc( sizeof( struct vchan_tbl_t ));
  vt->ht = *ht;
  vt->channel_size = 500;
  vt->channel_num = 0;
  vt->vchan = malloc( sizeof(struct vchan_t )*vt->channel_size );
  memset( vt->vchan, 0x0, sizeof(struct vchan_t )*vt->channel_size );
  return vt;
}

void release_vchan_tbl( struct vchan_tbl_t *vt )
{
  if ( vt->vchan );
  free( vt->vchan );
  free( vt );
}

int grow_vhcan_tbl( struct vchan_tbl_t *vt )
{
  int new_channel_size = vt->channel_size + 100;
  struct vchan_t * new_vchan_list = malloc( sizeof(struct vchan_t)*new_channel_size );
  if ( new_vchan_list == NULL )
    return 0;
  memcpy( new_vchan_list, vt->vchan, vt->channel_size*sizeof(struct vchan_t) );
  free( vt->vchan );
  vt->vchan = new_vchan_list;
  vt->channel_size = new_channel_size;
  return 1;
}

int tuner_input_sharing( struct hdhr_tuner_t *ht1, struct hdhr_tuner_t *ht2 )
{
  if ( ht1->cc_tuner == 1 && !strcmp( ht1->ip, ht2->ip ) )
    return 1;
  return 0;
}


#ifdef TEST_APP
static int scan_channel( void* device, int index, struct channel_entry_t *ce, int ce_channel_num, int ce_num )
{
  int found_channel = 0;
  struct hdhomerun_device_t *hd =(struct hdhomerun_device_t *)device;
  if ( hd == NULL ) {
    printf( "hdhomerun invalid handle\n");
    return -1;
  }

  char *ret_error;
  if (hdhomerun_device_tuner_lockkey_request(hd, &ret_error) <= 0) {
    fprintf(stderr, "failed to lock tuner\n");
    if (ret_error) {
      fprintf(stderr, "%s\n", ret_error);
    }
    return -1;
  }

  hdhomerun_device_set_tuner_target(hd, "none");

  char *channelmap;
  if (hdhomerun_device_get_tuner_channelmap(hd, &channelmap) <= 0) {
    fprintf(stderr, "failed to query channelmap from device\n");
    return -1;
  }

  const char *channelmap_scan_group = hdhomerun_channelmap_get_channelmap_scan_group(channelmap);
  if (!channelmap_scan_group) {
    fprintf(stderr, "unknown channelmap '%s'\n", channelmap);
    return -1;
  }

  if (hdhomerun_device_channelscan_init(hd, channelmap_scan_group) <= 0) {
    fprintf(stderr, "failed to initialize channel scan\n");
    return -1;
  }

  register_signal_handlers(sigabort_handler, sigabort_handler, siginfo_handler);

  int ret = 0, i;
  do {
    struct hdhomerun_channelscan_result_t result;
    char tune_str[32];
    char channel_name[32];
    int channel_num;
    ret = hdhomerun_device_channelscan_at( hd, index, &result );
    //ret = hdhomerun_device_channelscan_advance( hd, &result );
    if (ret <= 0) {
      break;
    }
    /* skip dumplicated channel*/
    for ( i = 0; i<ce_channel_num; i++ ) {
      if ( ce->frq == result.frequency )
        break;
    }
    if ( ce->frq == result.frequency )
      break;
    ret = hdhomerun_device_channelscan_detect( hd, &result );
    if (ret < 0) {
      break;
    }
    if (ret == 0) {
      continue;
    }

    if ( 0 )
    printf("LOCK: %s %s (ss=%u snq=%u seq=%u)\n", get_tune_string( result.channel_str, tune_str, sizeof(tune_str)),
      result.status.lock_str, result.status.signal_strength,
      result.status.signal_to_noise_quality, result.status.symbol_error_quality
    );

    channel_num = get_tune_channel( result.channel_str );
    for ( i = 0; i < result.program_count; i++) {
      struct hdhomerun_channelscan_program_t *program = &result.programs[i];
      if ( strstr( program->program_str, "encrypted" ) == NULL ) {
        int program_id = atoi( program->program_str );

        if ( !get_string_by_token( program->program_str, 2, channel_name, sizeof(channel_name), NULL ) ) {
          if ( !get_string_by_token( program->program_str, 1, channel_name, sizeof(channel_name), NULL ) )
            snprintf( channel_name, sizeof(channel_name), "%d.%d", channel_num, i );
          else {
            if ( !strcmp(channel_name, "0" ) )
              snprintf( channel_name, sizeof(channel_name), "%d.%d", channel_num, i );
          }
        }
        struct channel_entry_t *ce_p = &ce[ce_channel_num];
        snprintf( ce->dev_tuning, sizeof(ce->dev_tuning), "%s prog:%d", get_tune_string( result.channel_str, tune_str, sizeof(tune_str) ),
                 program_id );
        strncpy( ce_p->ch_name, channel_name, sizeof(ce_p->ch_name) );
        strncpy( ce_p->dev_name, device, sizeof(ce_p->dev_name) );
        ce_p->ch = found_channel+ce_channel_num;
        ce_p->frq = result.frequency;
        ce_p->av_inf[0] = 0x0;
        char stream_tar[32];
        snprintf( stream_tar, sizeof(stream_tar), "udp://%s:%u", CHANNE_SCAN_SRC, CHANNEL_SCAN_PORT );
        ret = tune_channel( hd, ce_p->dev_tuning, "", stream_tar );
        if ( ret > 0 )
          ret = parse_avinf( CHANNE_SCAN_SRC, CHANNEL_SCAN_PORT, ce_p->av_inf, sizeof(ce_p->av_inf), PARSE_TIMEOUT );
          if ( ret > 0 )
            ret = strstr( ce_p->av_inf, "ENCRYPTED" )==NULL && strstr( ce_p->av_inf, "NO-DATA" )==NULL ;
            if ( ret )
             if ( ++ce_channel_num > ce_num )
               break;
      }
    }
  } while ( 0 );

  hdhomerun_device_tuner_lockkey_release(hd);

  if (ret < 0) {
    fprintf(stderr, "communication error sending request to hdhomerun device\n");
  }
  return found_channel;
}

int scan_vchannel( void* device, int vchannel, struct channel_entry_t *ce )
{
  int ret;
  struct hdhomerun_device_t *hd =(struct hdhomerun_device_t *)device;
  if ( hd == NULL ) {
    sage_log(( _LOG_ERROR, 3, "hdhomerun invalid handle." ));
    return -1;
  }

  ce->state = 1;
  ce->ch = vchannel;
  ce->frq = 0;
  ce->av_inf[0] = 0x0;
  char stream_tar[32];
  snprintf( ce->ch_name, sizeof(ce->ch_name), "%d", vchannel );
  snprintf( ce->dev_tuning, sizeof(ce->dev_tuning), "vchan:%d", vchannel );
  snprintf( stream_tar, sizeof(stream_tar), "udp://%s:%u", CHANNE_SCAN_SRC, CHANNEL_SCAN_PORT );
  ret = tune_channel( device, ce->dev_tuning, "", stream_tar );
  if ( ret > 0 )
    ret = parse_avinf( CHANNE_SCAN_SRC, CHANNEL_SCAN_PORT, ce->av_inf, sizeof(ce->av_inf), PARSE_TIMEOUT );
    if ( ret > 0 )
      ret = strstr( ce->av_inf, "ENCRYPTED" )==NULL && strstr( ce->av_inf, "NO-DATA" )==NULL ;
  if ( ret <= 0 ) {
    ce->state = 0;
    return 0;
  }

  return 1;
}

static int _make_channel_entry_buffer( struct channel_entry_t *ce, char *buf, int size )
{
  int pos = 0;
  pos += snprintf( buf+pos, size-pos, "ch:%03d ", ce->ch );
  if ( ce->ch_name[0] )
    pos += snprintf( buf+pos, size-pos, "name:%s ", ce->ch_name );
  if ( ce->src_ip[0] && ce->src_port )
    pos += snprintf( buf+pos, size-pos, "ip:%s port:%d ", ce->src_ip, ce->src_port);
  if ( ce->epg_id[0] )
    pos += snprintf( buf+pos, size-pos, "epg:%s ", ce->epg_id );
  if ( ce->dev_name[0] )
    pos += snprintf( buf+pos, size-pos, "dev:%s ", ce->dev_name );
  if ( ce->dev_tuning[0] )
    pos += snprintf( buf+pos, size-pos, "tune:%s ", ce->dev_tuning );
  if ( ce->av_inf[0] )
    pos += snprintf( buf+pos, size-pos, "av:\"%s\" ", ce->av_inf );
  pos += snprintf( buf+pos, size-pos, "\n" );
  return pos;
}

static int _save_channel_entry( char* file_name, struct channel_entry_t *ce, int num )
{
  int i;
  char buf[2048];
  FILE *fp;
  fp = fopen( file_name, "w" );
  if ( fp == NULL ) {
    //printf( "Can't open file %s to save channel table, errno:%d\n", file_name, errno );
    return -1;
  }
  fputs( "#Google sagetv channel table ver 1.0., maxium 2048 bytes per line\n", fp );
  fprintf( fp, "total_channel:%d\n", num );
  for ( i = 0; i<num; i++ ) {
    _make_channel_entry_buffer( ce, buf, sizeof(buf) );
    fputs( buf, fp );
    ce++;
  }
  fclose( fp );
  return 1;
}

int main( int argc, char* argv[] )
{
  int  i, ret = 0 ;
  int tuner_count = 0;
  struct hdhr_tuner_t ht[16];

  ret = discover_device( ht, 16 );
  printf( "found tuners:%d\n", ret );
  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] );

      printf( "%d tuner:%s ip:%s type:%d cc:%d model:%s\n", i, ht[i].name, ht[i].ip, ht[i].type, ht[i].cc_tuner, ht[i].model );
    }
    tuner_count = ret;
  }

  // test channel scan
  if ( 0 ) {
    time_t t0 = time( NULL );
    struct channel_entry_t ce[400];
    int channel_num = 0;
    //channel_num = scan_all( "101007FD-0", ce, 400 );
    for ( i = 60; i<=70; i++ ) {
      ret = scan_channel( "101007FD-1", i, ce, channel_num, 400 );
      if ( ret < 0 || sigabort_flag )
        break;
      printf( "find channe:%d\n", ret );
      channel_num += ret;
    }
    printf( "time:%ld\n", time( NULL) - t0 );
   _save_channel_entry( "channel-scan.txt", ce, channel_num );
  }

  /*
  //test vchannel scan
  if ( 1 ) {
    struct hdhr_tuner_t *cc_ht = NULL;
    for ( i = 0; i<tuner_count; i++ ) {
      if ( ht[i].cc_tuner ) {
        cc_ht = &ht[i];
        break;
      }
    }


    if (  cc_ht != NULL ) {
      time_t t0 = time( NULL );
      struct vchan_tbl_t * vt = create_vchan_tbl( cc_ht );
      ret = get_vchannel_list( vt );
      if ( ret > 0 ) {
        int n;
        int channel_num = 0;
        struct channel_list_t *cl = create_channel_list( ret );
        for ( n = 1; n<vt->channel_num && channel_num < 500 ; n++ ) {
          printf( "TRACE %d %s\n", n, vt->vchan[n].guide_name );
          ret = scan_vchannel( vt, n, cl );
          if ( ret > 0 ) {
            struct channel_entry_t *ce_p = &cl->ce[channel_num];
            snprintf( ce_p->dev_name, sizeof(ce_p->dev_name), "HDHR.%s", device, sizeof(ce_p->dev_name) );
            channel_num++;
          }
          printf( "TRACE channel %d, %d\n", channel_num, n );
        }
         _save_channel_entry( "channel-scan.txt", cl );
      }
      release_vchan_tbl( vt );
      printf( "time:%ld\n", time( NULL) - t0 );
    }
  }
  */

  //test tune
  if ( 1 ) {
    //printf( "tuning %s \n", device[i] );
    char *dev_name = "1311A273-0"; //"101007FD-1";
    //ret = tune_channel( dev_name, "map:us-cable|auto:68", "343", "udp://226.0.0.1:4096" );
    ret = tune_channel( dev_name, "vchan:600", "", "udp://226.0.0.1:4096" );
    printf( "hit enter to stop\n" );
    getchar();
    ret = stop_channel( dev_name );
  }

  return ret;
}
#endif
