// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_CONNECTIVITY_NETWORK_MDNS_SERVICE_COMMON_TYPE_CONVERTERS_H_
#define SRC_CONNECTIVITY_NETWORK_MDNS_SERVICE_COMMON_TYPE_CONVERTERS_H_

#include <fuchsia/net/mdns/cpp/fidl.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/utf-utils/utf-utils.h>

#include "lib/fidl/cpp/type_converter.h"
#include "src/connectivity/network/mdns/service/common/mdns_names.h"
#include "src/connectivity/network/mdns/service/common/service_instance.h"
#include "src/connectivity/network/mdns/service/common/types.h"
#include "src/connectivity/network/mdns/service/encoding/dns_message.h"
#include "src/connectivity/network/mdns/service/mdns.h"
#include "src/lib/fsl/types/type_converters.h"
#include "src/lib/inet/socket_address.h"

namespace fidl {

template <>
struct TypeConverter<mdns::Media, fuchsia::net::mdns::Media> {
  static mdns::Media Convert(fuchsia::net::mdns::Media value) {
    switch (value) {
      case fuchsia::net::mdns::Media::WIRED:
        return mdns::Media::kWired;
      case fuchsia::net::mdns::Media::WIRELESS:
        return mdns::Media::kWireless;
      default:
        FX_DCHECK(value == (fuchsia::net::mdns::Media::WIRED | fuchsia::net::mdns::Media::WIRELESS))
            << "Unrecognized fuchsia::net::mdns::Media value " << static_cast<uint32_t>(value);
        return mdns::Media::kBoth;
    }
  }
};

template <>
struct TypeConverter<mdns::IpVersions, fuchsia::net::mdns::IpVersions> {
  static mdns::IpVersions Convert(fuchsia::net::mdns::IpVersions value) {
    switch (value) {
      case fuchsia::net::mdns::IpVersions::V4:
        return mdns::IpVersions::kV4;
      case fuchsia::net::mdns::IpVersions::V6:
        return mdns::IpVersions::kV6;
      default:
        FX_DCHECK(value ==
                  (fuchsia::net::mdns::IpVersions::V4 | fuchsia::net::mdns::IpVersions::V6));
        return mdns::IpVersions::kBoth;
    }
  }
};

template <>
struct TypeConverter<fuchsia::net::mdns::ServiceInstancePublicationCause, mdns::PublicationCause> {
  static fuchsia::net::mdns::ServiceInstancePublicationCause Convert(mdns::PublicationCause value) {
    switch (value) {
      case mdns::PublicationCause::kAnnouncement:
        return fuchsia::net::mdns::ServiceInstancePublicationCause::ANNOUNCEMENT;
      case mdns::PublicationCause::kQueryMulticastResponse:
        return fuchsia::net::mdns::ServiceInstancePublicationCause::QUERY_MULTICAST_RESPONSE;
      case mdns::PublicationCause::kQueryUnicastResponse:
        return fuchsia::net::mdns::ServiceInstancePublicationCause::QUERY_UNICAST_RESPONSE;
    }
  }
};

template <>
struct TypeConverter<fuchsia::net::mdns::PublicationCause, mdns::PublicationCause> {
  static fuchsia::net::mdns::PublicationCause Convert(mdns::PublicationCause value) {
    switch (value) {
      case mdns::PublicationCause::kAnnouncement:
        return fuchsia::net::mdns::PublicationCause::ANNOUNCEMENT;
      case mdns::PublicationCause::kQueryMulticastResponse:
        return fuchsia::net::mdns::PublicationCause::QUERY_MULTICAST_RESPONSE;
      case mdns::PublicationCause::kQueryUnicastResponse:
        return fuchsia::net::mdns::PublicationCause::QUERY_UNICAST_RESPONSE;
    }
  }
};

template <>
struct TypeConverter<std::string, std::vector<uint8_t>> {
  static std::string Convert(const std::vector<uint8_t>& value) {
    if(utfutils_is_valid_utf8(reinterpret_cast<const char *>(value.data()), value.size())) {
      return std::string(value.begin(), value.end());
    }
    return std::string();
  }
};

template <>
struct TypeConverter<std::vector<uint8_t>, std::string> {
  static std::vector<uint8_t> Convert(const std::string& value) {
    return std::vector<uint8_t>(value.data(), value.data() + value.size());
  }
};

template <>
struct TypeConverter<fuchsia::net::mdns::HostAddress, mdns::HostAddress> {
  static fuchsia::net::mdns::HostAddress Convert(const mdns::HostAddress& value) {
    return fuchsia::net::mdns::HostAddress{
        .address = static_cast<fuchsia::net::IpAddress>(value.address()),
        .interface = value.interface_id(),
        .ttl = value.ttl().get()};
  }
};

template <>
struct TypeConverter<mdns::HostAddress, inet::IpAddress> {
  static mdns::HostAddress Convert(const inet::IpAddress& value) {
    return mdns::HostAddress(value, 0, zx::sec(mdns::DnsResource::kShortTimeToLive));
  }
};

template <>
struct TypeConverter<fuchsia::net::SocketAddress, inet::SocketAddress> {
  static fuchsia::net::SocketAddress Convert(const inet::SocketAddress& value) {
    return static_cast<fuchsia::net::SocketAddress>(value);
  }
};

template <>
struct TypeConverter<std::unique_ptr<mdns::Mdns::Publication>, fuchsia::net::mdns::PublicationPtr> {
  static std::unique_ptr<mdns::Mdns::Publication> Convert(
      const fuchsia::net::mdns::PublicationPtr& value) {
    if (!value) {
      return nullptr;
    }

    auto publication = mdns::Mdns::Publication::Create(
        inet::IpPort::From_uint16_t(value->port),
        fidl::To<std::vector<std::vector<std::uint8_t>>>(value->text), value->srv_priority,
        value->srv_weight);

    auto ensure_uint32_secs = [](int64_t nanos) -> uint32_t {
      const int64_t secs = zx::nsec(nanos).to_secs();
      FX_CHECK(secs >= 0 && secs < std::numeric_limits<uint32_t>::max())
          << secs << " doesn't fit a uint32";
      return static_cast<uint32_t>(secs);
    };

    publication->ptr_ttl_seconds_ = ensure_uint32_secs(value->ptr_ttl);
    publication->srv_ttl_seconds_ = ensure_uint32_secs(value->srv_ttl);
    publication->txt_ttl_seconds_ = ensure_uint32_secs(value->txt_ttl);

    return publication;
  }
};

template <>
struct TypeConverter<std::unique_ptr<mdns::Mdns::Publication>,
                     fuchsia::net::mdns::ServiceInstancePublication> {
  static std::unique_ptr<mdns::Mdns::Publication> Convert(
      const fuchsia::net::mdns::ServiceInstancePublication& value) {
    constexpr uint16_t kDefaultSrvPriority = 0;
    constexpr uint16_t kDefaultSrvWeight = 0;

    if (!value.has_port()) {
      FX_LOGS(ERROR) << "ServiceInstancePublication has no port value, closing connection.";
      return nullptr;
    }

    std::vector<std::vector<uint8_t>> text;
    if (value.has_text()) {
      text = value.text();
    }

    uint16_t srv_priority = value.has_srv_priority() ? value.srv_priority() : kDefaultSrvPriority;
    uint16_t srv_weight = value.has_srv_weight() ? value.srv_weight() : kDefaultSrvWeight;

    auto result = mdns::Mdns::Publication::Create(inet::IpPort::From_uint16_t(value.port()), text,
                                                  srv_priority, srv_weight);

    if (value.has_ptr_ttl()) {
      const int64_t secs = zx::nsec(value.ptr_ttl()).to_secs();
      if (secs < 0 || secs > std::numeric_limits<uint32_t>::max()) {
        FX_LOGS(ERROR) << "ServiceInstancePublication has ptr_ttl value out of range, "
                          "closing connection.";
        return nullptr;
      }

      result->ptr_ttl_seconds_ = static_cast<uint32_t>(secs);
    }

    if (value.has_srv_ttl()) {
      const int64_t secs = zx::nsec(value.srv_ttl()).to_secs();
      if (secs < 0 || secs > std::numeric_limits<uint32_t>::max()) {
        FX_LOGS(ERROR) << "ServiceInstancePublication has srv_ttl value out of range, "
                          "closing connection.";
        return nullptr;
      }

      result->srv_ttl_seconds_ = static_cast<uint32_t>(secs);
    }

    if (value.has_txt_ttl()) {
      const int64_t secs = zx::nsec(value.txt_ttl()).to_secs();
      if (secs < 0 || secs > std::numeric_limits<uint32_t>::max()) {
        FX_LOGS(ERROR) << "ServiceInstancePublication has txt_ttl value out of range, "
                          "closing connection.";
        return nullptr;
      }

      result->txt_ttl_seconds_ = static_cast<uint32_t>(secs);
    }

    return result;
  }
};

template <>
struct TypeConverter<fuchsia::net::IpAddress, inet::SocketAddress> {
  static fuchsia::net::IpAddress Convert(const inet::SocketAddress& value) {
    return static_cast<fuchsia::net::IpAddress>(value.address());
  }
};

template <>
struct TypeConverter<fuchsia::net::mdns::ResourceType, mdns::DnsType> {
  static fuchsia::net::mdns::ResourceType Convert(const mdns::DnsType& value) {
    switch (value) {
      case mdns::DnsType::kPtr:
        return fuchsia::net::mdns::ResourceType::PTR;
      case mdns::DnsType::kAny:
        return fuchsia::net::mdns::ResourceType::ANY;
      default:
        FX_DCHECK(false) << "Asked to convert unexpected mdns::DnsType "
                         << static_cast<uint32_t>(value);
        return fuchsia::net::mdns::ResourceType::ANY;
    }
  }
};

template <typename T, typename U>
struct TypeConverter<std::vector<T>, std::vector<U>> {
  static std::vector<T> Convert(const std::vector<U>& value) {
    std::vector<T> result;
    std::transform(value.begin(), value.end(), std::back_inserter(result),
                   [](const U& u) { return fidl::To<T>(u); });
    return result;
  }
};

template <>
struct TypeConverter<fuchsia::net::mdns::ServiceInstance, mdns::ServiceInstance> {
  static fuchsia::net::mdns::ServiceInstance Convert(const mdns::ServiceInstance& value) {
    fuchsia::net::mdns::ServiceInstance result;
    result.set_service(value.service_name_);
    result.set_instance(value.instance_name_);
    result.set_srv_priority(value.srv_priority_);
    result.set_srv_weight(value.srv_weight_);
    result.set_target(value.target_name_);
    result.set_addresses(fidl::To<std::vector<fuchsia::net::SocketAddress>>(value.addresses_));
    result.set_text_strings(value.text_);

    // Deprecated items
    result.set_text(fidl::To<std::vector<std::string>>(value.text_));

    for (auto& address : result.addresses()) {
      if (address.is_ipv4()) {
        if (!result.has_ipv4_endpoint()) {
          result.set_ipv4_endpoint(fidl::Clone(address.ipv4()));
          if (result.has_ipv6_endpoint()) {
            break;
          }
        }
      } else {
        if (!result.has_ipv6_endpoint()) {
          result.set_ipv6_endpoint(fidl::Clone(address.ipv6()));
          if (result.has_ipv4_endpoint()) {
            break;
          }
        }
      }
    }

    return result;
  }
};

}  // namespace fidl

#endif  // SRC_CONNECTIVITY_NETWORK_MDNS_SERVICE_COMMON_TYPE_CONVERTERS_H_
