/*
 * Copyright (C) 2015 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.
 */

#define LOG_TAG "IpPrefix"

#include <binder/IpPrefix.h>
#include <vector>

#include <binder/IBinder.h>
#include <binder/Parcel.h>
#include <log/log.h>
#include <utils/Errors.h>

using android::BAD_TYPE;
using android::BAD_VALUE;
using android::NO_ERROR;
using android::Parcel;
using android::status_t;
using android::UNEXPECTED_NULL;

namespace android {

namespace net {

#define RETURN_IF_FAILED(calledOnce)                                     \
    {                                                                    \
        status_t returnStatus = calledOnce;                              \
        if (returnStatus) {                                              \
            ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
            return returnStatus;                                         \
         }                                                               \
    }

status_t IpPrefix::writeToParcel(Parcel* parcel) const {
    /*
     * Keep implementation in sync with writeToParcel() in
     * frameworks/base/core/java/android/net/IpPrefix.java.
     */
    std::vector<uint8_t> byte_vector;

    if (mIsIpv6) {
        const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&mUnion.mIn6Addr);
        byte_vector.insert(byte_vector.end(), bytes, bytes+sizeof(mUnion.mIn6Addr));
    } else {
        const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&mUnion.mInAddr);
        byte_vector.insert(byte_vector.end(), bytes, bytes+sizeof(mUnion.mIn6Addr));
    }

    RETURN_IF_FAILED(parcel->writeByteVector(byte_vector));
    RETURN_IF_FAILED(parcel->writeInt32(static_cast<int32_t>(mPrefixLength)));

    return NO_ERROR;
}

status_t IpPrefix::readFromParcel(const Parcel* parcel) {
    /*
     * Keep implementation in sync with readFromParcel() in
     * frameworks/base/core/java/android/net/IpPrefix.java.
     */
    std::vector<uint8_t> byte_vector;

    RETURN_IF_FAILED(parcel->readByteVector(&byte_vector));
    RETURN_IF_FAILED(parcel->readInt32(&mPrefixLength));

    if (byte_vector.size() == 16) {
        mIsIpv6 = true;
        memcpy((void*)&mUnion.mIn6Addr, &byte_vector[0], sizeof(mUnion.mIn6Addr));

    } else if (byte_vector.size() == 4) {
        mIsIpv6 = false;
        memcpy((void*)&mUnion.mInAddr, &byte_vector[0], sizeof(mUnion.mInAddr));

    } else {
        ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
        return BAD_VALUE;
    }

    return NO_ERROR;
}

const struct in6_addr& IpPrefix::getAddressAsIn6Addr() const
{
    return mUnion.mIn6Addr;
}

const struct in_addr& IpPrefix::getAddressAsInAddr() const
{
    return mUnion.mInAddr;
}

bool IpPrefix::getAddressAsIn6Addr(struct in6_addr* addr) const
{
    if (isIpv6()) {
        *addr = mUnion.mIn6Addr;
        return true;
    }
    return false;
}

bool IpPrefix::getAddressAsInAddr(struct in_addr* addr) const
{
    if (isIpv4()) {
        *addr = mUnion.mInAddr;
        return true;
    }
    return false;
}

bool IpPrefix::isIpv6() const
{
    return mIsIpv6;
}

bool IpPrefix::isIpv4() const
{
    return !mIsIpv6;
}

int32_t IpPrefix::getPrefixLength() const
{
    return mPrefixLength;
}

void IpPrefix::setAddress(const struct in6_addr& addr)
{
    mUnion.mIn6Addr = addr;
    mIsIpv6 = true;
}

void IpPrefix::setAddress(const struct in_addr& addr)
{
    mUnion.mInAddr = addr;
    mIsIpv6 = false;
}

void IpPrefix::setPrefixLength(int32_t prefix)
{
    mPrefixLength = prefix;
}

bool operator==(const IpPrefix& lhs, const IpPrefix& rhs)
{
    if (lhs.mIsIpv6 != rhs.mIsIpv6) {
        return false;
    }

    if (lhs.mPrefixLength != rhs.mPrefixLength) {
        return false;
    }

    if (lhs.mIsIpv6) {
        return 0 == memcmp(lhs.mUnion.mIn6Addr.s6_addr, rhs.mUnion.mIn6Addr.s6_addr, sizeof(struct in6_addr));
    }

    return 0 == memcmp(&lhs.mUnion.mInAddr, &rhs.mUnion.mInAddr, sizeof(struct in_addr));
}

}  // namespace net

}  // namespace android
