/*
 *
 *    Copyright (c) 2020-2021 Project CHIP Authors
 *    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
 *      Declaration of Commissioner Discovery Controller,
 *      a common class that manages state and callbacks
 *      for handling the Commissioner Discovery
 *      and User Directed Commissioning workflow
 *
 */

#pragma once

#include <app/OperationalSessionSetup.h>
#include <lib/core/CHIPConfig.h>
#include <lib/core/CHIPError.h>
#include <lib/core/NodeId.h>
#include <platform/CHIPDeviceLayer.h>
#include <platform/PlatformManager.h>
#include <protocols/user_directed_commissioning/UserDirectedCommissioning.h>

#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY

using chip::NodeId;
using chip::OperationalSessionSetup;
using chip::Protocols::UserDirectedCommissioning::UDCClientState;
using chip::Protocols::UserDirectedCommissioning::UserConfirmationProvider;
using chip::Protocols::UserDirectedCommissioning::UserDirectedCommissioningServer;
using chip::Transport::PeerAddress;

class DLL_EXPORT UserPrompter
{
public:
    /**
     * @brief
     *   Called to prompt the user for consent to allow the given commissioneeName/vendorId/productId to be commissioned.
     * For example "[commissioneeName] is requesting permission to cast to this TV, approve?"
     *
     * If user responds with OK then implementor should call CommissionerRespondOk();
     * If user responds with Cancel then implementor should call CommissionerRespondCancel();
     *
     *  @param[in]    vendorId           The vendorId in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    productId          The productId in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    commissioneeName   The commissioneeName in the DNS-SD advertisement of the requesting commissionee.
     *
     */
    virtual void PromptForCommissionOKPermission(uint16_t vendorId, uint16_t productId, const char * commissioneeName) = 0;

    /**
     * @brief
     *   Called to prompt the user to enter the setup passcode displayed by the given commissioneeName/vendorId/productId to be
     * commissioned. For example "Please enter passcode displayed in casting app."
     *
     * If user enters passcode then implementor should call CommissionerRespondPasscode(uint32_t passcode);
     * If user responds with Cancel then implementor should call CommissionerRespondCancel();
     *
     *  @param[in]    vendorId           The vendorId in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    productId          The productId in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    commissioneeName   The commissioneeName in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    pairingHint        The pairingHint in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    pairingInstruction The pairingInstruction in the DNS-SD advertisement of the requesting commissionee.
     *
     */
    virtual void PromptForCommissionPasscode(uint16_t vendorId, uint16_t productId, const char * commissioneeName,
                                             uint16_t pairingHint, const char * pairingInstruction) = 0;

    /**
     * @brief
     *   Called to when CancelCommissioning is received via UDC.
     * Indicates that commissioner can stop showing the passcode entry or display dialog.
     * For example, can show text such as "Commissioning cancelled by client" before hiding dialog.
     *
     *  @param[in]    vendorId           The vendorId in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    productId          The productId in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    commissioneeName   The commissioneeName in the DNS-SD advertisement of the requesting commissionee.
     *
     */
    virtual void HidePromptsOnCancel(uint16_t vendorId, uint16_t productId, const char * commissioneeName) = 0;

    /**
     * @brief
     *   Return true if this UserPrompter displays QR code along with passcode
     * When PromptWithCommissionerPasscode is called during Commissioner Passcode functionality.
     */
    virtual bool DisplaysPasscodeAndQRCode() = 0;

    /**
     * @brief
     *   Called to display the given setup passcode to the user,
     * for commissioning the given commissioneeName with the given vendorId and productId,
     * and provide instructions for where to enter it in the commissionee (when pairingHint and pairingInstruction are provided).
     * For example "Casting Passcode: [passcode]. For more instructions, click here."
     *
     *  @param[in]    vendorId           The vendorId in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    productId          The productId in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    commissioneeName   The commissioneeName in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    passcode           The passcode to display.
     *  @param[in]    pairingHint        The pairingHint in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    pairingInstruction The pairingInstruction in the DNS-SD advertisement of the requesting commissionee.
     *
     */
    virtual void PromptWithCommissionerPasscode(uint16_t vendorId, uint16_t productId, const char * commissioneeName,
                                                uint32_t passcode, uint16_t pairingHint, const char * pairingInstruction) = 0;

    /**
     * @brief
     *   Called to alert the user that commissioning has begun."
     *
     *  @param[in]    vendorId           The vendorid from the DAC of the new node.
     *  @param[in]    productId          The productid from the DAC of the new node.
     *  @param[in]    commissioneeName   The commissioneeName in the DNS-SD advertisement of the requesting commissionee.
     *
     */
    virtual void PromptCommissioningStarted(uint16_t vendorId, uint16_t productId, const char * commissioneeName) = 0;

    /**
     * @brief
     *   Called to prompt the user that commissioning and post-commissioning steps have completed successfully."
     *
     *  @param[in]    vendorId           The vendorid from the DAC of the new node.
     *  @param[in]    productId          The productid from the DAC of the new node.
     *  @param[in]    commissioneeName   The commissioneeName in the DNS-SD advertisement of the requesting commissionee.
     *
     */
    virtual void PromptCommissioningSucceeded(uint16_t vendorId, uint16_t productId, const char * commissioneeName) = 0;

    /**
     * @brief
     *   Called to prompt the user that commissioning and post-commissioning steps have failed."
     *
     *  @param[in]    commissioneeName   The commissioneeName in the DNS-SD advertisement of the requesting commissionee.
     *
     */
    virtual void PromptCommissioningFailed(const char * commissioneeName, CHIP_ERROR error) = 0;

    virtual ~UserPrompter() = default;
};

class DLL_EXPORT PasscodeService
{
public:
    /**
     * @brief
     *   Called to determine if the given target app is available to the commissionee with the given
     * vendorId/productId, and if so, return the passcode.
     *
     * This will be called by the main chip thread so any blocking work should be moved to a separate thread.
     *
     * After lookup and attempting to obtain the passcode, implementor should call HandleContentAppCheck();
     *
     *  @param[in]    vendorId           The vendorId in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    productId          The productId in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    rotatingId         The rotatingId in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    info               App info to look for.
     *
     */
    virtual void LookupTargetContentApp(uint16_t vendorId, uint16_t productId, chip::CharSpan rotatingId,
                                        chip::Protocols::UserDirectedCommissioning::TargetAppInfo & info) = 0;

    /**
     * @brief
     *   Called to get the commissioner-generated setup passcode.
     * Returns 0 if feature is disabled.
     *
     *  @param[in]    vendorId           The vendorId in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    productId          The productId in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    rotatingId         The rotatingId in the DNS-SD advertisement of the requesting commissionee.
     *
     */
    virtual uint32_t GetCommissionerPasscode(uint16_t vendorId, uint16_t productId, chip::CharSpan rotatingId) = 0;

    /**
     * @brief
     *   Called to get the setup passcode from the content app corresponding to the given vendorId/productId.
     *
     * This will be called by the main chip thread so any blocking work should be moved to a separate thread.
     *
     * After attempting to obtain the passcode, implementor should call HandleContentAppPasscodeResponse();
     *
     *  @param[in]    vendorId           The vendorId in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    productId          The productId in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    rotatingId         The rotatingId in the DNS-SD advertisement of the requesting commissionee.
     *
     */
    virtual void FetchCommissionPasscodeFromContentApp(uint16_t vendorId, uint16_t productId, chip::CharSpan rotatingId) = 0;

    virtual ~PasscodeService() = default;
};

class DLL_EXPORT AppInstallationService
{
public:
    /**
     * @brief
     *   Called to check if the given target app is available to the commissione with th given
     *   vendorId/productId
     *
     *  @param[in]    vendorId           The vendorId in the DNS-SD advertisement of the requesting commissionee.
     *  @param[in]    productId          The productId in the DNS-SD advertisement of the requesting commissionee.
     *
     */
    virtual bool LookupTargetContentApp(uint16_t vendorId, uint16_t productId) = 0;

    virtual ~AppInstallationService() = default;
};

class DLL_EXPORT PostCommissioningListener
{
public:
    /**
     * @brief
     *   Called to when commissioning completed to allow the listener to perform additional
     * steps such as binding and ACL creation.
     *
     *  @param[in]    vendorId           The vendorid from the DAC of the new node.
     *  @param[in]    productId          The productid from the DAC of the new node.
     *  @param[in]    nodeId             The node id for the newly commissioned node.
     *  @param[in]    exchangeMgr        The exchange manager to be used to get an exchange context.
     *  @param[in]    sessionHandle      A reference to an established session.
     *
     */
    virtual void CommissioningCompleted(uint16_t vendorId, uint16_t productId, NodeId nodeId,
                                        chip::Messaging::ExchangeManager & exchangeMgr,
                                        const chip::SessionHandle & sessionHandle) = 0;

    virtual ~PostCommissioningListener() = default;
};

class DLL_EXPORT CommissionerCallback
{
public:
    /**
     * @brief
     *   Called to notify the commissioner that commissioning can now proceed for
     * the node identified by the given arguments.
     *
     *  @param[in]    passcode            The passcode to use for the commissionee.
     *  @param[in]    longDiscriminator   The long discriminator for the commissionee.
     *  @param[in]    peerAddress         The peerAddress for the commissionee.
     *
     */
    virtual void ReadyForCommissioning(uint32_t passcode, uint16_t longDiscriminator, PeerAddress peerAddress) = 0;

    virtual ~CommissionerCallback() = default;
};

class CommissionerDiscoveryController : public chip::Protocols::UserDirectedCommissioning::UserConfirmationProvider
{
public:
    /**
     * This controller can only handle one outstanding UDC session at a time and will
     * reject attempts to start a second when one is outstanding.
     *
     * A session ends when post-commissioning completes:
     * - PostCommissioningSucceeded()
     * or when one of the following failure methods is called:
     * - PostCommissioningFailed()
     * - CommissioningFailed()
     *
     * Reset the state of this controller so that a new sessions will be accepted.
     */
    void ResetState();

    /**
     * Check whether we have a valid session (and reset state if not).
     */
    void ValidateSession();

    /**
     * UserConfirmationProvider callback.
     *
     * Notification that a UDC protocol message was received.
     *
     * This code will call the registered UserPrompter's PromptForCommissionOKPermission
     */
    void OnUserDirectedCommissioningRequest(UDCClientState state) override;

    /**
     * UserConfirmationProvider callback.
     *
     * Notification that a Cancel UDC protocol message was received.
     *
     * This code will call the registered UserPrompter's HidePromptsOnCancel
     */
    void OnCancel(UDCClientState state) override;

    /**
     * UserConfirmationProvider callback.
     *
     * Notification that a CommissionerPasscodeReady UDC protocol message was received.
     *
     * This code will trigger the Commissioner to begin commissioning
     */
    void OnCommissionerPasscodeReady(UDCClientState state) override;

    /**
     * This method should be called after the user has given consent for commissioning of the client
     * indicated in the UserPrompter's PromptForCommissionOKPermission callback
     */
    void Ok();
    void InternalOk();

    /**
     * This method should be called after the user has declined to give consent for commissioning of the client
     * indicated in the UserPrompter's PromptForCommissionOKPermission callback
     */
    void Cancel();

    /**
     * @brief
     *   Called with the result of attempting to obtain the passcode from the content app corresponding to the given
     * vendorId/productId.
     *
     *  @param[in]    passcode           Passcode for the given commissionee, or 0 if passcode cannot be obtained.
     *
     */
    void HandleContentAppPasscodeResponse(uint32_t passcode);
    void InternalHandleContentAppPasscodeResponse();

    /**
     * Cache the passcode to use for commissioning
     */
    inline void SetPasscode(uint32_t passcode) { mPasscode = passcode; }

    /**
     * @brief
     *   Called with the result of attempting to lookup and obtain the passcode from the content app corresponding to the given
     * target.
     *
     *  @param[in]    target             Target app info for app check.
     *  @param[in]    passcode           Passcode for the given commissionee, or 0 if passcode cannot be obtained.
     *
     */
    void HandleTargetContentAppCheck(chip::Protocols::UserDirectedCommissioning::TargetAppInfo target, uint32_t passcode);

    /**
     * This method should be called with the passcode for the client
     * indicated in the UserPrompter's PromptForCommissionPasscode callback
     */
    void CommissionWithPasscode(uint32_t passcode);
    void InternalCommissionWithPasscode();

    /**
     * This method should be called by the commissioner to indicate that commissioning succeeded.
     * The PostCommissioningCallback will then be invoked to complete setup
     *
     *  @param[in]    vendorId           The vendorid from the DAC of the new node.
     *  @param[in]    productId          The productid from the DAC of the new node.
     *  @param[in]    nodeId             The node id for the newly commissioned node.
     *  @param[in]    exchangeMgr        The exchange manager to be used to get an exchange context.
     *  @param[in]    sessionHandle      A reference to an established session.
     *
     */
    void CommissioningSucceeded(uint16_t vendorId, uint16_t productId, NodeId nodeId,
                                chip::Messaging::ExchangeManager & exchangeMgr, const chip::SessionHandle & sessionHandle);

    /**
     * This method should be called by the commissioner to indicate that commissioning failed.
     * The UserPrompter will then be invoked to notify the user of the failure.
     */
    void CommissioningFailed(CHIP_ERROR error);

    /**
     * This method should be called by the PostCommissioningListener to indicate that post-commissioning steps completed.
     * The PromptCommissioningSucceeded will then be invoked to notify the user of success.
     */
    void PostCommissioningSucceeded();

    /**
     * This method should be called by the PostCommissioningListener to indicate that post-commissioning steps failed.
     * The PromptCommissioningFailed will then be invoked to notify the user of failure.
     */
    void PostCommissioningFailed(CHIP_ERROR error);

    /**
     * Assign a DeviceCommissioner
     */
    inline void SetUserDirectedCommissioningServer(UserDirectedCommissioningServer * udcServer)
    {
        mUdcServer = udcServer;
        mUdcServer->SetUserConfirmationProvider(this);
    }

    /**
     * Assign a UserPromper
     */
    inline void SetUserPrompter(UserPrompter * userPrompter) { mUserPrompter = userPrompter; }

    /**
     * Assign a PasscodeService
     */
    inline void SetPasscodeService(PasscodeService * passcodeService) { mPasscodeService = passcodeService; }
    inline PasscodeService * GetPasscodeService() { return mPasscodeService; }

    /**
     * Assign an AppInstallationService
     */
    inline void SetAppInstallationService(AppInstallationService * appInstallationService)
    {
        mAppInstallationService = appInstallationService;
    }

    /**
     * Assign a Commissioner Callback to perform commissioning once user consent has been given
     */
    inline void SetCommissionerCallback(CommissionerCallback * commissionerCallback)
    {
        mCommissionerCallback = commissionerCallback;
    }

    /**
     * Assign a PostCommissioning Listener to perform post-commissioning operations
     */
    inline void SetPostCommissioningListener(PostCommissioningListener * postCommissioningListener)
    {
        mPostCommissioningListener = postCommissioningListener;
    }

    /**
     * Get the commissioneeName in the DNS-SD advertisement of the requesting commissionee.
     */
    const char * GetCommissioneeName();

    /**
     * Get the UDCClientState of the requesting commissionee.
     */
    UDCClientState * GetUDCClientState();

protected:
    bool mReady          = true; // ready to start commissioning
    bool mPendingConsent = false;
    char mCurrentInstance[chip::Dnssd::Commission::kInstanceNameMaxLength + 1];
    uint16_t mVendorId  = 0;
    uint16_t mProductId = 0;
    NodeId mNodeId      = 0;
    uint32_t mPasscode  = 0;

    UserDirectedCommissioningServer * mUdcServer           = nullptr;
    UserPrompter * mUserPrompter                           = nullptr;
    PasscodeService * mPasscodeService                     = nullptr;
    AppInstallationService * mAppInstallationService       = nullptr;
    CommissionerCallback * mCommissionerCallback           = nullptr;
    PostCommissioningListener * mPostCommissioningListener = nullptr;
};

#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
