/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2024,  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 "unix-stream-factory.hpp"

#include <boost/filesystem.hpp>

namespace nfd::face {

NFD_LOG_INIT(UnixStreamFactory);
NFD_REGISTER_PROTOCOL_FACTORY(UnixStreamFactory);

const std::string&
UnixStreamFactory::getId() noexcept
{
  static std::string id("unix");
  return id;
}

void
UnixStreamFactory::doProcessConfig(OptionalConfigSection configSection,
                                   FaceSystem::ConfigContext& context)
{
  // unix
  // {
  //   path /run/nfd/nfd.sock       ; on Linux
  //   path /var/run/nfd/nfd.sock   ; on other platforms
  // }

  m_wantCongestionMarking = context.generalConfig.wantCongestionMarking;

  if (!configSection) {
    if (!context.isDryRun && !m_channels.empty()) {
      NFD_LOG_WARN("Cannot disable Unix channel after initialization");
    }
    return;
  }

#ifdef __linux__
  std::string path = "/run/nfd/nfd.sock";
#else
  std::string path = "/var/run/nfd/nfd.sock";
#endif // __linux__

  for (const auto& [key, value] : *configSection) {
    if (key == "path") {
      path = value.get_value<std::string>();
    }
    else {
      NDN_THROW(ConfigFile::Error("Unrecognized option face_system.unix." + key));
    }
  }

  if (context.isDryRun) {
    return;
  }

  auto channel = this->createChannel(path);
  if (!channel->isListening()) {
    channel->listen(this->addFace, nullptr);
  }
}

shared_ptr<UnixStreamChannel>
UnixStreamFactory::createChannel(const std::string& socketPath)
{
  auto normalizedPath = boost::filesystem::weakly_canonical(boost::filesystem::absolute(socketPath));
  unix_stream::Endpoint endpoint(normalizedPath.string());

  auto it = m_channels.find(endpoint);
  if (it != m_channels.end())
    return it->second;

  auto channel = make_shared<UnixStreamChannel>(endpoint, m_wantCongestionMarking);
  m_channels[endpoint] = channel;
  return channel;
}

std::vector<shared_ptr<const Channel>>
UnixStreamFactory::doGetChannels() const
{
  return getChannelsFromMap(m_channels);
}

} // namespace nfd::face
