/*
 *  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 CoAP API.
 */

#include "openthread-core-config.h"

#include <openthread/coap.h>

#include "coap/coap_header.hpp"
#include "common/instance.hpp"

#if OPENTHREAD_ENABLE_APPLICATION_COAP

using namespace ot;

void otCoapHeaderInit(otCoapHeader *aHeader, otCoapType aType, otCoapCode aCode)
{
    Coap::Header *header = static_cast<Coap::Header *>(aHeader);
    header->Init(aType, aCode);
}

void otCoapHeaderSetToken(otCoapHeader *aHeader, const uint8_t *aToken, uint8_t aTokenLength)
{
    static_cast<Coap::Header *>(aHeader)->SetToken(aToken, aTokenLength);
}

void otCoapHeaderGenerateToken(otCoapHeader *aHeader, uint8_t aTokenLength)
{
    static_cast<Coap::Header *>(aHeader)->SetToken(aTokenLength);
}

otError otCoapHeaderAppendContentFormatOption(otCoapHeader *aHeader, otCoapOptionContentFormat aContentFormat)
{
    return static_cast<Coap::Header *>(aHeader)->AppendContentFormatOption(aContentFormat);
}

otError otCoapHeaderAppendOption(otCoapHeader *aHeader, const otCoapOption *aOption)
{
    return static_cast<Coap::Header *>(aHeader)->AppendOption(*static_cast<const Coap::Header::Option *>(aOption));
}

otError otCoapHeaderAppendUintOption(otCoapHeader *aHeader, uint16_t aNumber, uint32_t aValue)
{
    return static_cast<Coap::Header *>(aHeader)->AppendUintOption(aNumber, aValue);
}

otError otCoapHeaderAppendObserveOption(otCoapHeader *aHeader, uint32_t aObserve)
{
    return static_cast<Coap::Header *>(aHeader)->AppendObserveOption(aObserve);
}

otError otCoapHeaderAppendUriPathOptions(otCoapHeader *aHeader, const char *aUriPath)
{
    return static_cast<Coap::Header *>(aHeader)->AppendUriPathOptions(aUriPath);
}

otError otCoapHeaderAppendMaxAgeOption(otCoapHeader *aHeader, uint32_t aMaxAge)
{
    return static_cast<Coap::Header *>(aHeader)->AppendMaxAgeOption(aMaxAge);
}

otError otCoapHeaderAppendUriQueryOption(otCoapHeader *aHeader, const char *aUriQuery)
{
    return static_cast<Coap::Header *>(aHeader)->AppendUriQueryOption(aUriQuery);
}

otError otCoapHeaderSetPayloadMarker(otCoapHeader *aHeader)
{
    return static_cast<Coap::Header *>(aHeader)->SetPayloadMarker();
}

void otCoapHeaderSetMessageId(otCoapHeader *aHeader, uint16_t aMessageId)
{
    return static_cast<Coap::Header *>(aHeader)->SetMessageId(aMessageId);
}

otCoapType otCoapHeaderGetType(const otCoapHeader *aHeader)
{
    return static_cast<const Coap::Header *>(aHeader)->GetType();
}

otCoapCode otCoapHeaderGetCode(const otCoapHeader *aHeader)
{
    return static_cast<const Coap::Header *>(aHeader)->GetCode();
}

const char *otCoapHeaderCodeToString(const otCoapHeader *aHeader)
{
    return static_cast<const Coap::Header *>(aHeader)->CodeToString();
}

uint16_t otCoapHeaderGetMessageId(const otCoapHeader *aHeader)
{
    return static_cast<const Coap::Header *>(aHeader)->GetMessageId();
}

uint8_t otCoapHeaderGetTokenLength(const otCoapHeader *aHeader)
{
    return static_cast<const Coap::Header *>(aHeader)->GetTokenLength();
}

const uint8_t *otCoapHeaderGetToken(const otCoapHeader *aHeader)
{
    return static_cast<const Coap::Header *>(aHeader)->GetToken();
}

const otCoapOption *otCoapHeaderGetFirstOption(otCoapHeader *aHeader)
{
    return static_cast<const otCoapOption *>(static_cast<Coap::Header *>(aHeader)->GetFirstOption());
}

const otCoapOption *otCoapHeaderGetNextOption(otCoapHeader *aHeader)
{
    return static_cast<const otCoapOption *>(static_cast<Coap::Header *>(aHeader)->GetNextOption());
}

otMessage *otCoapNewMessage(otInstance *aInstance, const otCoapHeader *aHeader)
{
    Message * message;
    Instance &instance = *static_cast<Instance *>(aInstance);

    VerifyOrExit(aHeader != NULL, message = NULL);
    message = instance.GetApplicationCoap().NewMessage(*(static_cast<const Coap::Header *>(aHeader)));
exit:
    return message;
}

otError otCoapSendRequest(otInstance *          aInstance,
                          otMessage *           aMessage,
                          const otMessageInfo * aMessageInfo,
                          otCoapResponseHandler aHandler,
                          void *                aContext)
{
    Instance &instance = *static_cast<Instance *>(aInstance);

    return instance.GetApplicationCoap().SendMessage(
        *static_cast<Message *>(aMessage), *static_cast<const Ip6::MessageInfo *>(aMessageInfo), aHandler, aContext);
}

otError otCoapStart(otInstance *aInstance, uint16_t aPort)
{
    Instance &instance = *static_cast<Instance *>(aInstance);

    return instance.GetApplicationCoap().Start(aPort);
}

otError otCoapStop(otInstance *aInstance)
{
    Instance &instance = *static_cast<Instance *>(aInstance);

    return instance.GetApplicationCoap().Stop();
}

otError otCoapAddResource(otInstance *aInstance, otCoapResource *aResource)
{
    Instance &instance = *static_cast<Instance *>(aInstance);

    return instance.GetApplicationCoap().AddResource(*static_cast<Coap::Resource *>(aResource));
}

void otCoapRemoveResource(otInstance *aInstance, otCoapResource *aResource)
{
    Instance &instance = *static_cast<Instance *>(aInstance);

    instance.GetApplicationCoap().RemoveResource(*static_cast<Coap::Resource *>(aResource));
}

void otCoapSetDefaultHandler(otInstance *aInstance, otCoapRequestHandler aHandler, void *aContext)
{
    Instance &instance = *static_cast<Instance *>(aInstance);

    instance.GetApplicationCoap().SetDefaultHandler(aHandler, aContext);
}

otError otCoapSendResponse(otInstance *aInstance, otMessage *aMessage, const otMessageInfo *aMessageInfo)
{
    Instance &instance = *static_cast<Instance *>(aInstance);

    return instance.GetApplicationCoap().SendMessage(*static_cast<Message *>(aMessage),
                                                     *static_cast<const Ip6::MessageInfo *>(aMessageInfo));
}

#endif // OPENTHREAD_ENABLE_APPLICATION_COAP
