// 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;
};

void *dev_init(int *num)
{
  int i;
  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);
    if (devices->hdhrs == NULL) {
      free(devices);
      return NULL;
    }
    memset(devices->hdhrs, 0,
           sizeof(sizeof(struct hdhr_tuner_t) * MAX_TUNER_NUM));
    devices->list_num = MAX_TUNER_NUM;
    devices->tuner_num = discover_devices(devices->hdhrs, MAX_TUNER_NUM);
    for (i = 0; i < devices->tuner_num; i++) {
      sage_log((_LOG_TRACE, 3, "hdhr:%d %s %s %s %s", i,
                devices->hdhrs[i].tuner_name, devices->hdhrs[i].model,
                devices->hdhrs[i].cc_tuner ? "CableCard" : "ATSC",
                devices->hdhrs[i].firmware));
    }
    *num = devices->tuner_num;
  }
  return devices;
}

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
    int ch = -1;

    // channel format: xx
    // xx=Comcast virtual channel
    if (sscanf(channel, "%d", &ch) == 1) {
      ret = tune_cable_vchannel(hdhr->hd, ch, stream_tar);
      goto out;
    }

    // other channel formats
    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_atsc_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_atsc_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;
}
