// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/network/socket_address_parser.h"

#include "base/basictypes.h"
#include "base/logging.h"
#include "net/base/ip_address.h"
#include "starboard/memory.h"
#include "url/third_party/mozilla/url_parse.h"
#include "url/url_canon.h"
#include "url/url_canon_ip.h"

namespace cobalt {
namespace network {

bool ParseSocketAddress(const char* spec, const url::Component& host_component,
                        SbSocketAddress* out_socket_address) {
  DCHECK(out_socket_address);

  unsigned char address_v4[net::IPAddress::kIPv4AddressSize];
  int num_ipv4_components = 0;

  // IPv4AddressToNumber will return either IPV4, BROKEN, or NEUTRAL.  If the
  // input IP address is IPv6, then NEUTRAL will be returned, and a different
  // function will be used to covert the hostname to IPv6 address.
  // If the return value is IPV4, then address will be in network byte order.
  url::CanonHostInfo::Family family = url::IPv4AddressToNumber(
      spec, host_component, address_v4, &num_ipv4_components);

  switch (family) {
    case url::CanonHostInfo::IPV4:
      if (num_ipv4_components != net::IPAddress::kIPv4AddressSize) {
        return false;
      }

      SbMemorySet(out_socket_address, 0, sizeof(SbSocketAddress));
      out_socket_address->type = kSbSocketAddressTypeIpv4;
      DCHECK_GE(sizeof(address_v4),
                static_cast<std::size_t>(num_ipv4_components));
      SbMemoryCopy(out_socket_address->address, address_v4,
                   num_ipv4_components);

      return true;
    case url::CanonHostInfo::NEUTRAL:
#if SB_API_VERSION >= 12
      if (!SbSocketIsIpv6Supported()) {
        return false;
      }
#endif
#if SB_API_VERSION >= 12 || SB_HAS(IPV6)
      unsigned char address_v6[net::IPAddress::kIPv6AddressSize];
      if (!url::IPv6AddressToNumber(spec, host_component, address_v6)) {
        break;
      }

      SbMemorySet(out_socket_address, 0, sizeof(SbSocketAddress));
      out_socket_address->type = kSbSocketAddressTypeIpv6;
      static_assert(sizeof(address_v6) == net::IPAddress::kIPv6AddressSize, "");
      SbMemoryCopy(out_socket_address->address, address_v6, sizeof(address_v6));
      return true;
#else
      return false;
#endif
    case url::CanonHostInfo::BROKEN:
      break;
    case url::CanonHostInfo::IPV6:
      NOTREACHED() << "Invalid return value from IPv4AddressToNumber.";
      break;
    default:
      NOTREACHED() << "Unexpected return value from IPv4AddressToNumber: "
                   << family;
      break;
  }

  return false;
}

}  // namespace network
}  // namespace cobalt
