/*
 *
 *    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;

    /**
     * @brief
     *   Called to prompt the user for consent to allow the app commissioneeName/vendorId/productId to be installed.
     * For example "[commissioneeName] is requesting permission to install app 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 PromptForAppInstallOKPermission(uint16_t vendorId, uint16_t productId, const char * commissioneeName) = 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
     *
     * This will be called by the main chip thread so any blocking work should be moved to a separate thread.
     *
     *  @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
