/*
 *
 *    Copyright (c) 2020-2021 Project CHIP Authors
 *    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 contains implementation of Device class. The objects of this
 *    class will be used by Controller applications to interact with CHIP
 *    devices. The class provides mechanism to construct, send and receive
 *    messages to and from the corresponding CHIP devices.
 */

#include <controller/CommissioneeDeviceProxy.h>

#include <app/CommandSender.h>
#include <app/ReadPrepareParams.h>
#include <app/util/DataModelHandler.h>
#include <lib/core/CHIPCore.h>
#include <lib/core/CHIPEncoding.h>
#include <lib/core/CHIPSafeCasts.h>
#include <lib/core/ErrorStr.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/SafeInt.h>
#include <lib/support/logging/CHIPLogging.h>

using namespace chip::Callback;

namespace chip {

CHIP_ERROR CommissioneeDeviceProxy::SendCommands(app::CommandSender * commandObj, Optional<System::Clock::Timeout> timeout)
{
    VerifyOrReturnError(mSecureSession, CHIP_ERROR_INCORRECT_STATE);
    VerifyOrReturnError(commandObj != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    VerifyOrReturnError(mSecureSession, CHIP_ERROR_MISSING_SECURE_SESSION);
    return commandObj->SendCommandRequest(mSecureSession.Get().Value(), timeout);
}

void CommissioneeDeviceProxy::OnSessionReleased()
{
    mState = ConnectionState::NotConnected;
}

void CommissioneeDeviceProxy::CloseSession()
{
    VerifyOrReturn(mState == ConnectionState::SecureConnected);
    if (mSecureSession)
    {
        mSecureSession->AsSecureSession()->MarkForEviction();
    }

    mState = ConnectionState::NotConnected;
    mPairing.Clear();
}

chip::Optional<SessionHandle> CommissioneeDeviceProxy::DetachSecureSession()
{
    auto session = mSecureSession.Get();
    mSecureSession.Release();
    mState = ConnectionState::NotConnected;
    mPairing.Clear();
    return session;
}

void CommissioneeDeviceProxy::UpdateDeviceData(const Transport::PeerAddress & addr, const ReliableMessageProtocolConfig & config)
{
    mDeviceAddress = addr;

    // Initialize PASE session state with any MRP parameters that DNS-SD has provided.
    // It can be overridden by PASE session protocol messages that include MRP parameters.
    mPairing.SetRemoteMRPConfig(config);

    if (!mSecureSession)
    {
        // Nothing needs to be done here.  It's not an error to not have a
        // secureSession.  For one thing, we could have gotten an different
        // UpdateAddress already and that caused connections to be torn down and
        // whatnot.
        return;
    }

    Transport::SecureSession * secureSession = mSecureSession.Get().Value()->AsSecureSession();
    secureSession->SetPeerAddress(addr);
}

CHIP_ERROR CommissioneeDeviceProxy::SetConnected(const SessionHandle & session)
{
    VerifyOrReturnError(mState == ConnectionState::Connecting, CHIP_ERROR_INCORRECT_STATE);
    VerifyOrReturnError(session->AsSecureSession()->IsPASESession(), CHIP_ERROR_INVALID_ARGUMENT);

    if (!mSecureSession.Grab(session))
    {
        mState = ConnectionState::NotConnected;
        return CHIP_ERROR_INTERNAL;
    }

    mState = ConnectionState::SecureConnected;
    return CHIP_NO_ERROR;
}

CommissioneeDeviceProxy::~CommissioneeDeviceProxy()
{
    auto session = GetSecureSession();
    if (session.HasValue())
    {
        session.Value()->AsSecureSession()->MarkForEviction();
    }
}

CHIP_ERROR CommissioneeDeviceProxy::SetPeerId(ByteSpan rcac, ByteSpan noc)
{
    CompressedFabricId compressedFabricId;
    NodeId nodeId;
    ReturnErrorOnFailure(Credentials::ExtractNodeIdCompressedFabricIdFromOpCerts(rcac, noc, compressedFabricId, nodeId));
    mPeerId = PeerId().SetCompressedFabricId(compressedFabricId).SetNodeId(nodeId);
    return CHIP_NO_ERROR;
}

} // namespace chip
