/*
 *
 *    Copyright (c) 2013-2017 Nest Labs, Inc.
 *    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.
 */

/**
 *    @file
 *      This file implements an object for a Weave Service Provisioning
 *      profile unsolicited initiator (client).
 *
 */

#include <Weave/Core/WeaveCore.h>
#include <Weave/Core/WeaveTLV.h>
#include <Weave/Support/CodeUtils.h>
#include <Weave/Core/WeaveEncoding.h>
#include <Weave/Profiles/WeaveProfiles.h>
#include "ServiceProvisioning.h"
#include <Weave/Profiles/common/CommonProfile.h>
#include <Weave/Profiles/security/WeaveCert.h>
#include <Weave/Profiles/service-directory/ServiceDirectory.h>

namespace nl {
namespace Weave {
namespace Profiles {
namespace ServiceProvisioning {

using namespace nl::Weave::Profiles::Security;
using namespace nl::Weave::Encoding;
using namespace nl::Weave::TLV;

WEAVE_ERROR RegisterServicePairAccountMessage::Encode(PacketBuffer *msgBuf)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint32_t msgLen;
    uint8_t *p;

    msgLen = 2 + 2 + 2 + 2 + 8 + ServiceConfigLen + AccountIdLen + PairingTokenLen + PairingInitDataLen;
    VerifyOrExit(msgBuf->AvailableDataLength() >= msgLen, err = WEAVE_ERROR_MESSAGE_TOO_LONG);

    p = msgBuf->Start();
    LittleEndian::Write16(p, AccountIdLen);
    LittleEndian::Write16(p, ServiceConfigLen);
    LittleEndian::Write16(p, PairingTokenLen);
    LittleEndian::Write16(p, PairingInitDataLen);
    LittleEndian::Write64(p, ServiceId);
    memcpy(p, AccountId, AccountIdLen); p += AccountIdLen;
    memcpy(p, ServiceConfig, ServiceConfigLen); p += ServiceConfigLen;
    memcpy(p, PairingToken, PairingTokenLen); p += PairingTokenLen;
    memcpy(p, PairingInitData, PairingInitDataLen);
    msgBuf->SetDataLength(msgLen);

exit:
    return err;
}

WEAVE_ERROR RegisterServicePairAccountMessage::Decode(PacketBuffer *msgBuf, RegisterServicePairAccountMessage& msg)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint16_t dataLen = msgBuf->DataLength();
    const uint8_t *p = msgBuf->Start();

    VerifyOrExit(dataLen >= 2 + 2 + 2 + 2 + 8, err = WEAVE_ERROR_INVALID_MESSAGE_LENGTH);
    msg.AccountIdLen = LittleEndian::Read16(p);
    msg.ServiceConfigLen = LittleEndian::Read16(p);
    msg.PairingTokenLen = LittleEndian::Read16(p);
    msg.PairingInitDataLen = LittleEndian::Read16(p);
    msg.ServiceId = LittleEndian::Read64(p);

    VerifyOrExit(dataLen == 2 + 2 + 2 + 2 + 8 + msg.AccountIdLen + msg.ServiceConfigLen + msg.PairingTokenLen + msg.PairingInitDataLen,
                 err = WEAVE_ERROR_INVALID_MESSAGE_LENGTH);

    msg.AccountId        = (const char *)p;
    msg.ServiceConfig    = p + msg.AccountIdLen;
    msg.PairingToken     = p + msg.AccountIdLen + msg.ServiceConfigLen;
    msg.PairingInitData  = p + msg.AccountIdLen + msg.ServiceConfigLen + msg.PairingTokenLen;

exit:
    return err;
}

WEAVE_ERROR UpdateServiceMessage::Encode(PacketBuffer *msgBuf)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint32_t msgLen;
    uint8_t *p;

    msgLen = 2 + 8 + ServiceConfigLen;
    VerifyOrExit(msgBuf->AvailableDataLength() >= msgLen, err = WEAVE_ERROR_MESSAGE_TOO_LONG);

    p = msgBuf->Start();
    LittleEndian::Write16(p, ServiceConfigLen);
    LittleEndian::Write64(p, ServiceId);
    memcpy(p, ServiceConfig, ServiceConfigLen);
    msgBuf->SetDataLength(msgLen);

exit:
    return err;
}

WEAVE_ERROR UpdateServiceMessage::Decode(PacketBuffer *msgBuf, UpdateServiceMessage& msg)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint16_t dataLen = msgBuf->DataLength();
    const uint8_t *p = msgBuf->Start();

    VerifyOrExit(dataLen >= 2 + 8, err = WEAVE_ERROR_INVALID_MESSAGE_LENGTH);
    msg.ServiceConfigLen = LittleEndian::Read16(p);
    msg.ServiceId = LittleEndian::Read64(p);

    VerifyOrExit(dataLen == 2 + 8 + msg.ServiceConfigLen, err = WEAVE_ERROR_INVALID_MESSAGE_LENGTH);

    msg.ServiceConfig = p;

exit:
    return err;
}

WEAVE_ERROR PairDeviceToAccountMessage::Encode(PacketBuffer *msgBuf)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint32_t msgLen;
    uint8_t *p;

    msgLen = 2 + 2 + 2 + 2 + 8 + 8 + AccountIdLen + PairingTokenLen + PairingInitDataLen + DeviceInitDataLen;
    VerifyOrExit(msgBuf->AvailableDataLength() >= msgLen, err = WEAVE_ERROR_MESSAGE_TOO_LONG);

    p = msgBuf->Start();
    LittleEndian::Write16(p, AccountIdLen);
    LittleEndian::Write16(p, PairingTokenLen);
    LittleEndian::Write16(p, PairingInitDataLen);
    LittleEndian::Write16(p, DeviceInitDataLen);
    LittleEndian::Write64(p, ServiceId);
    LittleEndian::Write64(p, FabricId);
    memcpy(p, AccountId, AccountIdLen); p += AccountIdLen;
    memcpy(p, PairingToken, PairingTokenLen); p += PairingTokenLen;
    memcpy(p, PairingInitData, PairingInitDataLen); p += PairingInitDataLen;
    memcpy(p, DeviceInitData, DeviceInitDataLen);
    msgBuf->SetDataLength(msgLen);

exit:
    return err;
}

WEAVE_ERROR PairDeviceToAccountMessage::Decode(PacketBuffer *msgBuf, PairDeviceToAccountMessage& msg)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint16_t dataLen = msgBuf->DataLength();
    const uint8_t *p = msgBuf->Start();

    VerifyOrExit(dataLen >= 2 + 2 + 2 + 2 + 8 + 8, err = WEAVE_ERROR_INVALID_MESSAGE_LENGTH);
    msg.AccountIdLen = LittleEndian::Read16(p);
    msg.PairingTokenLen = LittleEndian::Read16(p);
    msg.PairingInitDataLen = LittleEndian::Read16(p);
    msg.DeviceInitDataLen = LittleEndian::Read16(p);
    msg.ServiceId = LittleEndian::Read64(p);
    msg.FabricId = LittleEndian::Read64(p);

    VerifyOrExit(dataLen == 2 + 2 + 2 + 2 + 8 + 8 + msg.AccountIdLen + msg.PairingTokenLen + msg.PairingInitDataLen + msg.DeviceInitDataLen,
                 err = WEAVE_ERROR_INVALID_MESSAGE_LENGTH);

    msg.AccountId        = (const char *)p;
    msg.PairingToken     = p + msg.AccountIdLen;
    msg.PairingInitData  = p + msg.AccountIdLen + msg.PairingTokenLen;
    msg.DeviceInitData   = p + msg.AccountIdLen + msg.PairingTokenLen + msg.PairingInitDataLen;

exit:
    return err;
}

NL_DLL_EXPORT WEAVE_ERROR EncodeServiceConfig(WeaveCertificateSet& certSet, const char *dirHostName, uint16_t dirPort, uint8_t *outBuf, uint16_t& outLen)
{
    WEAVE_ERROR err;
    TLVWriter writer;

    writer.Init(outBuf, outLen);

    {
        TLVType containingType1;

        err = writer.StartContainer(ProfileTag(kWeaveProfile_ServiceProvisioning, kTag_ServiceConfig), kTLVType_Structure, containingType1);
        SuccessOrExit(err);

        {
            TLVType containingType2;

            err = writer.StartContainer(ContextTag(kTag_ServiceConfig_CACerts), kTLVType_Array, containingType2);
            SuccessOrExit(err);

            err = certSet.SaveCerts(writer, NULL, true);
            SuccessOrExit(err);

            err = writer.EndContainer(containingType2);
            SuccessOrExit(err);
        }

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
        {
            TLVType containingType3;

            err = writer.StartContainer(ContextTag(kTag_ServiceEndPoint), kTLVType_Structure, containingType3);
            SuccessOrExit(err);

            err = writer.Put(ContextTag(kTag_ServiceEndPoint_Id), (uint64_t)kServiceEndpoint_Directory);
            SuccessOrExit(err);

            {
                TLVType containingType4;

                err = writer.StartContainer(ContextTag(kTag_ServiceEndPoint_Addresses), kTLVType_Array, containingType4);
                SuccessOrExit(err);

                {
                    TLVType containingType5;

                    err = writer.StartContainer(AnonymousTag, kTLVType_Structure, containingType5);
                    SuccessOrExit(err);

                    err = writer.PutString(ContextTag(kTag_ServiceEndPointAddress_HostName), dirHostName);
                    SuccessOrExit(err);

                    if (dirPort != WEAVE_PORT)
                    {
                        err = writer.Put(ContextTag(kTag_ServiceEndPointAddress_Port), dirPort);
                        SuccessOrExit(err);
                    }

                    err = writer.EndContainer(containingType5);
                    SuccessOrExit(err);
                }

                err = writer.EndContainer(containingType4);
                SuccessOrExit(err);
            }

            err = writer.EndContainer(containingType3);
            SuccessOrExit(err);
        }
#endif // WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY

        err = writer.EndContainer(containingType1);
        SuccessOrExit(err);
    }

    err = writer.Finalize();
    SuccessOrExit(err);

    outLen = writer.GetLengthWritten();

exit:
    return err;
}


} // ServiceProvisioning
} // namespace Profiles
} // namespace Weave
} // namespace nl
