int main() {

  // get necessary config
  // -----------------------------------------------
  Jansson j;
  if(!j.load("youtube.cfg", true)) {
    RX_ERROR("Make sure that you created the youtube.cfg; we're using that config to authorize ourself");
    return EXIT_FAILURE;
  }
  
  std::string client_id;
  std::string client_secret;
  std::string auth_code;

  j.getString("/client_id", client_id);
  j.getString("/client_secret", client_secret);
  j.getString("/auth_code", auth_code);

  if(!client_id.size() || !client_secret.size() || !auth_code.size()) {
    RX_ERROR("One of the configuration options is empty! Did you set the auth code? See html/index.html and readme.");
    return EXIT_FAILURE;
  }

  // test an upload with some garbage json 
  // -----------------------------------------------
  YouTube yt;
  if(!yt.setup(client_id, client_secret)) {
    RX_ERROR("Cannot setup the youtube API handler");
    return EXIT_FAILURE;
  }

  if(!yt.hasAccessToken()) {
    RX_VERBOSE("Fetching access token");
    if(!yt.exchangeAuthCode(auth_code)) {
      RX_ERROR("Cannot update the access token");
      return EXIT_FAILURE;
    }
  }

  YouTubeVideo video;
  video.title = "some title";
  video.filename = rx_to_data_path("test.mov");
  video.datapath = false;
  video.video_resource_json = "_invalid_json_"; 
  video.bytes_total = rx_get_file_size(video.filename);

  YouTubeUploadStart uploader;
  if(uploader.start(video, yt.getAccessToken())) {
    RX_ERROR("TEST FAILED, uploader should return false on error");
  }
  else {
    RX_ERROR("TEST SUCCEEDED!");
  }

  return EXIT_SUCCESS;
}
// @todo - we need to construct the correct video resource json
bool YouTubeModel::addVideoToUploadQueue(YouTubeVideo video) {

  if(!video.filename.size()) {
    RX_ERROR("Cannot add a video which has no filename set");
    return false;
  }

  std::string filepath = video.filename;
  if(video.datapath) {
    filepath = rx_to_data_path(video.filename);
  }

  size_t fsize = rx_get_file_size(filepath);
  if(!fsize) {
    RX_ERROR("Filesize of %s returned %ld", filepath.c_str(), fsize);
    return false;
  }

#if USE_JSON_PACK
  // @todo - libjansson is used as DLL, and json_dumps
  // is supposed to free() the memory; this is icky and 
  // libjansson should free() any allocated mem as it's used
  // as a dll
  std::string video_json;
  char* video_resource = NULL;
  json_t* body = NULL;
  
  if(!video.video_resource_json.size()) {
    body = json_pack("{ s: {s:s}, s: { s:s, s:i, s:s, s:s } }",
                             "status", "privacyStatus", "private", 
                             "snippet", "tags", video.tags.c_str(), 
                             "categoryId", video.category,  
                             "description", video.description.c_str(), 
                             "title", video.title.c_str());
 
    video_resource = json_dumps(body, JSON_INDENT(0));
    json_decref(body);

    video_json.assign(video_resource, strlen(video_resource));

    if(!video_resource) {
      RX_ERROR("Cannot create JSON video resource string");
      return false;
    }
  }
  else {
    video_json = video.video_resource_json;
  }
#else
  std::string video_json;

  if(!video.video_resource_json.size()) {
    std::stringstream ss;

    ss << "{ \"status\": { \"privacyStatus\" : \"private\" }, "
       <<   "\"snippet\": {"
       <<       "\"title\":\"" << video.title << "\", "
       <<       "\"tags\":\"" << video.tags << "\", "
       <<       "\"categoryId\":" << video.category << ", "
       <<       "\"description\":\"" << video.description << "\""
       <<    "}"
       << "}";

    video_json = ss.str();
  }
  else {
    video_json = video.video_resource_json;
  }

#endif

  bool r = db.insert("videos")
    .use("filename", video.filename)
    .use("state", YT_VIDEO_STATE_NONE)
    .use("bytes_total", fsize)
    .use("video_resource_json", video_json)
    .use("datapath", (video.datapath) ? 1 : 0)
    .use("title", video.title)
    .use("description", video.description)
    .use("tags", video.tags)
    .use("privacy_status", video.privacy_status)
    .use("category", video.category)
    .execute();

#if USE_JSON_PACK
  if(video_resource) {
    free(video_resource);  
    video_resource = NULL;
  }
#endif

  if(r) {
    RX_VERBOSE("Added video to the queue: %s", video.filename.c_str());
  }
  else {
    RX_ERROR("Error while trying to add: %s to the video upload queue", video.filename.c_str());
  }

  return r;
}