/*
 *  Copyright (c) 2016, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 *   This file implements the OpenThread IPv6 API.
 */

#include "openthread-core-config.h"

#include <openthread/ip6.h>

#include "common/as_core_type.hpp"
#include "common/locator_getters.hpp"
#include "common/logging.hpp"
#include "utils/slaac_address.hpp"

using namespace ot;

otError otIp6SetEnabled(otInstance *aInstance, bool aEnabled)
{
    Error     error    = kErrorNone;
    Instance &instance = AsCoreType(aInstance);

#if OPENTHREAD_CONFIG_LINK_RAW_ENABLE
    VerifyOrExit(!instance.Get<Mac::LinkRaw>().IsEnabled(), error = kErrorInvalidState);
#endif

    if (aEnabled)
    {
        instance.Get<ThreadNetif>().Up();
    }
    else
    {
        instance.Get<ThreadNetif>().Down();
    }

#if OPENTHREAD_CONFIG_LINK_RAW_ENABLE
exit:
#endif
    return error;
}

bool otIp6IsEnabled(otInstance *aInstance)
{
    return AsCoreType(aInstance).Get<ThreadNetif>().IsUp();
}

const otNetifAddress *otIp6GetUnicastAddresses(otInstance *aInstance)
{
    return AsCoreType(aInstance).Get<ThreadNetif>().GetUnicastAddresses().GetHead();
}

otError otIp6AddUnicastAddress(otInstance *aInstance, const otNetifAddress *aAddress)
{
    return AsCoreType(aInstance).Get<ThreadNetif>().AddExternalUnicastAddress(AsCoreType(aAddress));
}

otError otIp6RemoveUnicastAddress(otInstance *aInstance, const otIp6Address *aAddress)
{
    return AsCoreType(aInstance).Get<ThreadNetif>().RemoveExternalUnicastAddress(AsCoreType(aAddress));
}

const otNetifMulticastAddress *otIp6GetMulticastAddresses(otInstance *aInstance)
{
    return AsCoreType(aInstance).Get<ThreadNetif>().GetMulticastAddresses().GetHead();
}

otError otIp6SubscribeMulticastAddress(otInstance *aInstance, const otIp6Address *aAddress)
{
    return AsCoreType(aInstance).Get<ThreadNetif>().SubscribeExternalMulticast(AsCoreType(aAddress));
}

otError otIp6UnsubscribeMulticastAddress(otInstance *aInstance, const otIp6Address *aAddress)
{
    return AsCoreType(aInstance).Get<ThreadNetif>().UnsubscribeExternalMulticast(AsCoreType(aAddress));
}

bool otIp6IsMulticastPromiscuousEnabled(otInstance *aInstance)
{
    return AsCoreType(aInstance).Get<ThreadNetif>().IsMulticastPromiscuousEnabled();
}

void otIp6SetMulticastPromiscuousEnabled(otInstance *aInstance, bool aEnabled)
{
    AsCoreType(aInstance).Get<ThreadNetif>().SetMulticastPromiscuous(aEnabled);
}

void otIp6SetReceiveCallback(otInstance *aInstance, otIp6ReceiveCallback aCallback, void *aCallbackContext)
{
    AsCoreType(aInstance).Get<Ip6::Ip6>().SetReceiveDatagramCallback(aCallback, aCallbackContext);
}

void otIp6SetAddressCallback(otInstance *aInstance, otIp6AddressCallback aCallback, void *aCallbackContext)
{
    AsCoreType(aInstance).Get<ThreadNetif>().SetAddressCallback(aCallback, aCallbackContext);
}

bool otIp6IsReceiveFilterEnabled(otInstance *aInstance)
{
    return AsCoreType(aInstance).Get<Ip6::Ip6>().IsReceiveIp6FilterEnabled();
}

void otIp6SetReceiveFilterEnabled(otInstance *aInstance, bool aEnabled)
{
    AsCoreType(aInstance).Get<Ip6::Ip6>().SetReceiveIp6FilterEnabled(aEnabled);
}

otError otIp6Send(otInstance *aInstance, otMessage *aMessage)
{
    return AsCoreType(aInstance).Get<Ip6::Ip6>().SendRaw(AsCoreType(aMessage),
                                                         !OPENTHREAD_CONFIG_IP6_ALLOW_LOOP_BACK_HOST_DATAGRAMS);
}

otMessage *otIp6NewMessage(otInstance *aInstance, const otMessageSettings *aSettings)
{
    return AsCoreType(aInstance).Get<Ip6::Ip6>().NewMessage(0, Message::Settings::From(aSettings));
}

otMessage *otIp6NewMessageFromBuffer(otInstance *             aInstance,
                                     const uint8_t *          aData,
                                     uint16_t                 aDataLength,
                                     const otMessageSettings *aSettings)
{
    return (aSettings != nullptr)
               ? AsCoreType(aInstance).Get<Ip6::Ip6>().NewMessage(aData, aDataLength, AsCoreType(aSettings))
               : AsCoreType(aInstance).Get<Ip6::Ip6>().NewMessage(aData, aDataLength);
}

otError otIp6AddUnsecurePort(otInstance *aInstance, uint16_t aPort)
{
    return AsCoreType(aInstance).Get<Ip6::Filter>().AddUnsecurePort(aPort);
}

otError otIp6RemoveUnsecurePort(otInstance *aInstance, uint16_t aPort)
{
    return AsCoreType(aInstance).Get<Ip6::Filter>().RemoveUnsecurePort(aPort);
}

void otIp6RemoveAllUnsecurePorts(otInstance *aInstance)
{
    AsCoreType(aInstance).Get<Ip6::Filter>().RemoveAllUnsecurePorts();
}

const uint16_t *otIp6GetUnsecurePorts(otInstance *aInstance, uint8_t *aNumEntries)
{
    return AsCoreType(aInstance).Get<Ip6::Filter>().GetUnsecurePorts(*aNumEntries);
}

bool otIp6IsAddressEqual(const otIp6Address *aFirst, const otIp6Address *aSecond)
{
    return AsCoreType(aFirst) == AsCoreType(aSecond);
}

bool otIp6ArePrefixesEqual(const otIp6Prefix *aFirst, const otIp6Prefix *aSecond)
{
    return AsCoreType(aFirst) == AsCoreType(aSecond);
}

otError otIp6AddressFromString(const char *aString, otIp6Address *aAddress)
{
    return AsCoreType(aAddress).FromString(aString);
}

void otIp6AddressToString(const otIp6Address *aAddress, char *aBuffer, uint16_t aSize)
{
    AsCoreType(aAddress).ToString(aBuffer, aSize);
}

void otIp6SockAddrToString(const otSockAddr *aSockAddr, char *aBuffer, uint16_t aSize)
{
    AsCoreType(aSockAddr).ToString(aBuffer, aSize);
}

void otIp6PrefixToString(const otIp6Prefix *aPrefix, char *aBuffer, uint16_t aSize)
{
    AsCoreType(aPrefix).ToString(aBuffer, aSize);
}

uint8_t otIp6PrefixMatch(const otIp6Address *aFirst, const otIp6Address *aSecond)
{
    OT_ASSERT(aFirst != nullptr && aSecond != nullptr);

    return AsCoreType(aFirst).PrefixMatch(AsCoreType(aSecond));
}

bool otIp6IsAddressUnspecified(const otIp6Address *aAddress)
{
    return AsCoreType(aAddress).IsUnspecified();
}

otError otIp6SelectSourceAddress(otInstance *aInstance, otMessageInfo *aMessageInfo)
{
    Error                             error = kErrorNone;
    const Ip6::Netif::UnicastAddress *netifAddr;

    netifAddr = AsCoreType(aInstance).Get<Ip6::Ip6>().SelectSourceAddress(AsCoreType(aMessageInfo));
    VerifyOrExit(netifAddr != nullptr, error = kErrorNotFound);
    aMessageInfo->mSockAddr = netifAddr->GetAddress();

exit:
    return error;
}

#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
otError otIp6RegisterMulticastListeners(otInstance *                            aInstance,
                                        const otIp6Address *                    aAddresses,
                                        uint8_t                                 aAddressNum,
                                        const uint32_t *                        aTimeout,
                                        otIp6RegisterMulticastListenersCallback aCallback,
                                        void *                                  aContext)
{
    return AsCoreType(aInstance).Get<MlrManager>().RegisterMulticastListeners(aAddresses, aAddressNum, aTimeout,
                                                                              aCallback, aContext);
}
#endif

#if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE

bool otIp6IsSlaacEnabled(otInstance *aInstance)
{
    return AsCoreType(aInstance).Get<Utils::Slaac>().IsEnabled();
}

void otIp6SetSlaacEnabled(otInstance *aInstance, bool aEnabled)
{
    Instance &instance = AsCoreType(aInstance);

    if (aEnabled)
    {
        instance.Get<Utils::Slaac>().Enable();
    }
    else
    {
        instance.Get<Utils::Slaac>().Disable();
    }
}

void otIp6SetSlaacPrefixFilter(otInstance *aInstance, otIp6SlaacPrefixFilter aFilter)
{
    AsCoreType(aInstance).Get<Utils::Slaac>().SetFilter(aFilter);
}

#endif // OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE

#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE

otError otIp6SetMeshLocalIid(otInstance *aInstance, const otIp6InterfaceIdentifier *aIid)
{
    return AsCoreType(aInstance).Get<Mle::MleRouter>().SetMeshLocalIid(AsCoreType(aIid));
}

#endif

const char *otIp6ProtoToString(uint8_t aIpProto)
{
    return Ip6::Ip6::IpProtoToString(aIpProto);
}
