/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2023,  Regents of the University of California,
 *                           Arizona Board of Regents,
 *                           Colorado State University,
 *                           University Pierre & Marie Curie, Sorbonne University,
 *                           Washington University in St. Louis,
 *                           Beijing Institute of Technology,
 *                           The University of Memphis.
 *
 * This file is part of NFD (Named Data Networking Forwarding Daemon).
 * See AUTHORS.md for complete list of NFD authors and contributors.
 *
 * NFD is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "ndn-fch-discovery.hpp"

#include <boost/algorithm/string.hpp>
#include <boost/asio/ip/tcp.hpp>

#include <regex>
#include <sstream>

namespace ndn::autoconfig {

/**
 * A partial and specialized copy of ndn::FaceUri implementation
 *
 * Consider removing in favor of a library-provided URL parsing, if project
 * includes such a library.
 */
class Url
{
public:
  Url(const std::string& url)
    : m_isValid(false)
  {
    static const std::regex protocolExp("(\\w+\\d?(\\+\\w+)?)://([^/]*)(\\/[^?]*)?");
    std::smatch protocolMatch;
    if (!std::regex_match(url, protocolMatch, protocolExp)) {
      return;
    }
    m_scheme = protocolMatch[1];
    std::string authority = protocolMatch[3];
    m_path = protocolMatch[4];

    // pattern for IPv6 address enclosed in [ ], with optional port number
    static const std::regex v6Exp("^\\[([a-fA-F0-9:]+)\\](?:\\:(\\d+))?$");
    // pattern for IPv4-mapped IPv6 address, with optional port number
    static const std::regex v4MappedV6Exp("^\\[::ffff:(\\d+(?:\\.\\d+){3})\\](?:\\:(\\d+))?$");
    // pattern for IPv4/hostname/fd/ifname, with optional port number
    static const std::regex v4HostExp("^([^:]+)(?:\\:(\\d+))?$");

    if (authority.empty()) {
      // UNIX, internal
    }
    else {
      std::smatch match;
      bool isV6 = std::regex_match(authority, match, v6Exp);
      if (isV6 ||
          std::regex_match(authority, match, v4MappedV6Exp) ||
          std::regex_match(authority, match, v4HostExp)) {
        m_host = match[1];
        m_port = match[2];
      }
      else {
        return;
      }
    }
    if (m_port.empty()) {
      m_port = "80";
    }
    if (m_path.empty()) {
      m_path = "/";
    }
    m_isValid = true;
  }

  bool
  isValid() const
  {
    return m_isValid;
  }

  const std::string&
  getScheme() const
  {
    return m_scheme;
  }

  const std::string&
  getHost() const
  {
    return m_host;
  }

  const std::string&
  getPort() const
  {
    return m_port;
  }

  const std::string&
  getPath() const
  {
    return m_path;
  }

private:
  bool m_isValid;
  std::string m_scheme;
  std::string m_host;
  std::string m_port;
  std::string m_path;
};

class HttpException : public std::runtime_error
{
public:
  using std::runtime_error::runtime_error;
};

NdnFchDiscovery::NdnFchDiscovery(const std::string& url)
  : m_url(url)
{
}

void
NdnFchDiscovery::doStart()
{
  try {
    boost::asio::ip::tcp::iostream requestStream;
    requestStream.expires_after(std::chrono::seconds(3));

    Url url(m_url);
    if (!url.isValid()) {
      NDN_THROW(HttpException("Invalid NDN-FCH URL: " + m_url));
    }
    if (!boost::iequals(url.getScheme(), "http")) {
      NDN_THROW(HttpException("Only http:// NDN-FCH URLs are supported"));
    }

    requestStream.connect(url.getHost(), url.getPort());
    if (!requestStream) {
      NDN_THROW(HttpException("HTTP connection error to " + m_url));
    }

    requestStream << "GET " << url.getPath() << " HTTP/1.0\r\n";
    requestStream << "Host: " << url.getHost() << ":" << url.getPort() << "\r\n";
    requestStream << "Accept: */*\r\n";
    requestStream << "Cache-Control: no-cache\r\n";
    requestStream << "Connection: close\r\n\r\n";
    requestStream.flush();

    std::string statusLine;
    std::getline(requestStream, statusLine);
    if (!requestStream) {
      NDN_THROW(HttpException("HTTP communication error"));
    }

    std::stringstream responseStream(statusLine);
    std::string httpVersion;
    responseStream >> httpVersion;
    unsigned int statusCode;
    responseStream >> statusCode;
    std::string statusMessage;

    std::getline(responseStream, statusMessage);
    if (!static_cast<bool>(requestStream) || httpVersion.substr(0, 5) != "HTTP/") {
      NDN_THROW(HttpException("HTTP communication error"));
    }
    if (statusCode != 200) {
      boost::trim(statusMessage);
      NDN_THROW(HttpException("HTTP request failed: " + to_string(statusCode) + " " + statusMessage));
    }
    std::string header;
    while (std::getline(requestStream, header) && header != "\r")
      ;

    std::string hubHost;
    requestStream >> hubHost;
    if (hubHost.empty()) {
      NDN_THROW(HttpException("NDN-FCH did not return hub host"));
    }

    this->provideHubFaceUri("udp://" + hubHost);
  }
  catch (const std::runtime_error& e) {
    this->fail(e.what());
  }
}

} // namespace ndn::autoconfig
