// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "p2p/client/peer_selector.h"
#include "p2p/client/service_finder.h"
#include "p2p/common/clock.h"
#include "p2p/common/constants.h"
#include "p2p/common/util.h"

#include <glib-object.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>

#include <cassert>
#include <cerrno>
#include <memory>

#include <base/bind.h>
#include <base/command_line.h>
#include <base/logging.h>
#include <base/rand_util.h>
#include <base/strings/string_number_conversions.h>
#include <metrics/metrics_library.h>

using std::map;
using std::string;
using std::vector;

/* Global pointer to the PeerSelector being used. Only used from the signal
 * handler of SIGTERM. */
static p2p::client::PeerSelector* volatile global_peer_selector = NULL;

static void sigterm_handler(int signum) {
  /* This function is non-reentrant since is only used to handle SIGTERM.
   * A second SIGTERM signal will wait until this call finishes. */
  if (global_peer_selector)
    global_peer_selector->Abort();
}

static void Usage(FILE* output) {
  fprintf(output,
    "Usage:\n"
    "  p2p-client [OPTION..]\n"
    "\n"
    "Options:\n"
    " --help             Show help options\n"
    " --list-all         Scan network and list available files\n"
    " --list-urls=ID     Like --list-all but only show peers for ID\n"
    " --get-url=ID       Scan for ID and pick a suitable peer\n"
    " --num-connections  Show total number of connections in the LAN\n"
    " -v=NUMBER          Verbosity level (default: 0)\n"
    " --minimum-size=NUM When used with --get-url, scans for files\n"
    "                    with at least NUM bytes (default: 1).\n"
    "\n");
}

// Lists all URLs discovered via |finder|. If |id| is not the empty
// string then only lists URLs matching it.
static void ListUrls(p2p::client::ServiceFinder* finder,
                     const std::string &id) {
  vector<string> files = finder->AvailableFiles();

  for (auto const& file_name : files) {
    if (id == "" || file_name == id) {
      printf("%s\n", file_name.c_str());
      vector<const p2p::client::Peer*> peers =
          finder->GetPeersForFile(file_name);
      for (auto const& peer : peers) {
        map<string, size_t>::const_iterator file_size_it =
            peer->files.find(file_name);
        printf(" address %s, port %d, size %zu, num_connections %d\n",
               peer->address.c_str(), peer->port,
               (file_size_it == peer->files.end() ? -1 : file_size_it->second),
               peer->num_connections);
      }
    }
  }
}

int main(int argc, char* argv[]) {
  std::unique_ptr<p2p::client::ServiceFinder> finder;

  g_type_init();
  base::CommandLine::Init(argc, argv);
  logging::LoggingSettings logging_settings;
  logging_settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
  logging_settings.lock_log = logging::LOCK_LOG_FILE;
  logging_settings.delete_old = logging::APPEND_TO_OLD_LOG_FILE;
  logging::InitLogging(logging_settings);
  p2p::util::SetupSyslog("p2p-client", true /* include_pid */);

  base::CommandLine* cl = base::CommandLine::ForCurrentProcess();

  // If help is requested, show usage and exit immediately
  if (cl->HasSwitch("help")) {
    Usage(stdout);
    return 0;
  }

  // Get us a ServiceFinder and look up all peers - this takes a couple
  // of seconds. This can fail if e.g. avahi-daemon is not running.
  finder.reset(p2p::client::ServiceFinder::Construct());
  if (finder == NULL)
    return 1;

  p2p::common::Clock clock;
  p2p::client::PeerSelector peer_selector(finder.get(), &clock);
  // The Metrics Library interface for reporting UMA stats.

  if (cl->HasSwitch("list-all")) {
    finder->Lookup();
    ListUrls(finder.get(), "");
  } else if (cl->HasSwitch("num-connections")) {
    finder->Lookup();
    int num_connections = finder->NumTotalConnections();
    printf("%d\n", num_connections);
  } else if (cl->HasSwitch("get-url")) {
    string id = cl->GetSwitchValueNative("get-url");
    uint64_t minimum_size = 1;
    if (cl->HasSwitch("minimum-size")) {
      string minimum_size_str = cl->GetSwitchValueNative("minimum-size");
      if (!base::StringToUint64(minimum_size_str, &minimum_size)) {
        LOG(ERROR) << "Invalid --minimum-size argument";
        return 1;
      }
    }

    // Register the SIGTERM signal handler in order to abort the
    // GetUrlAndWait() call, but reporting the metric.
    global_peer_selector = &peer_selector;
    signal(SIGTERM, sigterm_handler);

    string url = peer_selector.GetUrlAndWait(id, minimum_size);

    // Remove the global pointer reference to avoid a Abort() call due a
    // SIGTERM after the pointed object is destroyed.
    global_peer_selector = NULL;

    // Report the metrics.
    MetricsLibrary metrics_lib;
    metrics_lib.Init();
    peer_selector.ReportMetrics(&metrics_lib);

    if (url == "")
      return 1;
    printf("%s\n", url.c_str());
  } else if (cl->HasSwitch("list-urls")) {
    string id = cl->GetSwitchValueNative("list-urls");
    finder->Lookup();
    ListUrls(finder.get(), id);
  } else {
    Usage(stderr);
    return 1;
  }

  return 0;
}
