/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * 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 "netdutils/InternetAddresses.h"

#include <string>

#include <android-base/stringprintf.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>

namespace android {

using base::StringPrintf;

namespace netdutils {

std::string IPAddress::toString() const noexcept {
    char repr[INET6_ADDRSTRLEN] = "\0";

    switch (mData.family) {
        case AF_UNSPEC:
            return "<unspecified>";
        case AF_INET: {
            const in_addr v4 = mData.ip.v4;
            inet_ntop(AF_INET, &v4, repr, sizeof(repr));
            break;
        }
        case AF_INET6: {
            const in6_addr v6 = mData.ip.v6;
            inet_ntop(AF_INET6, &v6, repr, sizeof(repr));
            break;
        }
        default:
            return "<unknown_family>";
    }

    if (mData.family == AF_INET6 && mData.scope_id > 0) {
        return StringPrintf("%s%%%u", repr, mData.scope_id);
    }

    return repr;
}

bool IPAddress::forString(const std::string& repr, IPAddress* ip) {
    const addrinfo hints = {
            .ai_flags = AI_NUMERICHOST | AI_NUMERICSERV,
    };
    addrinfo* res;
    const int ret = getaddrinfo(repr.c_str(), nullptr, &hints, &res);
    ScopedAddrinfo res_cleanup(res);
    if (ret != 0) {
        return false;
    }

    bool rval = true;
    switch (res[0].ai_family) {
        case AF_INET: {
            sockaddr_in* sin = (sockaddr_in*) res[0].ai_addr;
            if (ip) *ip = IPAddress(sin->sin_addr);
            break;
        }
        case AF_INET6: {
            sockaddr_in6* sin6 = (sockaddr_in6*) res[0].ai_addr;
            if (ip) *ip = IPAddress(sin6->sin6_addr, sin6->sin6_scope_id);
            break;
        }
        default:
            rval = false;
            break;
    }

    return rval;
}

IPPrefix::IPPrefix(const IPAddress& ip, int length) : IPPrefix(ip) {
    // Silently treat CIDR lengths like "-1" as meaning the full bit length
    // appropriate to the address family.
    if (length < 0) return;
    if (length >= mData.cidrlen) return;

    switch (mData.family) {
        case AF_UNSPEC:
            break;
        case AF_INET: {
            const in_addr_t mask = (length > 0) ? (~0U) << (IPV4_ADDR_BITS - length) : 0U;
            mData.ip.v4.s_addr &= htonl(mask);
            mData.cidrlen = static_cast<uint8_t>(length);
            break;
        }
        case AF_INET6: {
            // The byte in which this CIDR length falls.
            const int which = length / 8;
            const int mask = (length % 8 == 0) ? 0 : 0xff << (8 - length % 8);
            mData.ip.v6.s6_addr[which] &= mask;
            for (int i = which + 1; i < IPV6_ADDR_LEN; i++) {
                mData.ip.v6.s6_addr[i] = 0U;
            }
            mData.cidrlen = static_cast<uint8_t>(length);
            break;
        }
        default:
            // TODO: Complain bitterly about possible data corruption?
            return;
    }
}

bool IPPrefix::isUninitialized() const noexcept {
    static const internal_::compact_ipdata empty{};
    return mData == empty;
}

bool IPPrefix::forString(const std::string& repr, IPPrefix* prefix) {
    size_t index = repr.find('/');
    if (index == std::string::npos) return false;

    // Parse the IP address.
    IPAddress ip;
    if (!IPAddress::forString(repr.substr(0, index), &ip)) return false;

    // Parse the prefix length. Can't use base::ParseUint because it accepts non-base 10 input.
    const char* prefixString = repr.c_str() + index + 1;
    if (!isdigit(*prefixString)) return false;
    char* endptr;
    unsigned long prefixlen = strtoul(prefixString, &endptr, 10);
    if (*endptr != '\0') return false;

    uint8_t maxlen = (ip.family() == AF_INET) ? 32 : 128;
    if (prefixlen > maxlen) return false;

    *prefix = IPPrefix(ip, prefixlen);
    return true;
}

std::string IPPrefix::toString() const noexcept {
    return StringPrintf("%s/%d", ip().toString().c_str(), mData.cidrlen);
}

std::string IPSockAddr::toString() const noexcept {
    switch (mData.family) {
        case AF_INET6:
            return StringPrintf("[%s]:%u", ip().toString().c_str(), mData.port);
        default:
            return StringPrintf("%s:%u", ip().toString().c_str(), mData.port);
    }
}

}  // namespace netdutils
}  // namespace android
