/*
 *
 *    Copyright (c) 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
 *      DeviceControllerFactory is a singleton utility class that manages the
 *      runtime DeviceControllerSystemState and provides APIs to setup DeviceControllers
 *      and DeviceCommissioners.
 *
 *      Together with the SystemState this class implicitly manages the lifecycle of the underlying
 *      CHIP stack. It lazily initializes the CHIPStack when setting up Controllers if the SystemState
 *      was previously shutdown.
 */

#pragma once

#include <controller/CHIPDeviceController.h>
#include <controller/CHIPDeviceControllerSystemState.h>
#include <credentials/GroupDataProvider.h>
#include <credentials/OperationalCertificateStore.h>
#include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
#include <inet/InetInterface.h>
#include <lib/support/TimerDelegate.h>
#include <protocols/secure_channel/SessionResumptionStorage.h>

#include <optional>

namespace chip {

namespace Controller {

struct SetupParams
{
    OperationalCredentialsDelegate * operationalCredentialsDelegate = nullptr;

    /* The following keypair must correspond to the public key used for generating
    controllerNOC. It's used by controller to establish CASE sessions with devices */
    Crypto::P256Keypair * operationalKeypair = nullptr;

    /**
     * Controls whether or not the operationalKeypair should be owned by the
     * caller.  By default, this is false, but if the keypair cannot be
     * serialized, then setting this to true will allow the caller to manage
     * this keypair's lifecycle.
     */
    bool hasExternallyOwnedOperationalKeypair = false;

    /* The following certificates must be in x509 DER format */
    ByteSpan controllerNOC;
    ByteSpan controllerICAC;
    ByteSpan controllerRCAC;

    //
    // This must be set to a valid, operational VendorId value associated with
    // the controller/commissioner.
    //
    chip::VendorId controllerVendorId = VendorId::Unspecified;

    // The Device Pairing Delegated used to initialize a Commissioner
    DevicePairingDelegate * pairingDelegate = nullptr;

    /**
     * Controls whether we permit multiple DeviceController instances to exist
     * on the same logical fabric (identified by the tuple of the fabric's
     * root public key + fabric id).
     *
     * Each controller instance will be associated with its own FabricIndex.
     * This pivots the FabricTable to tracking identities instead of fabrics,
     * represented by FabricInfo instances that can have colliding logical fabrics.
     *
     */
    bool permitMultiControllerFabrics = false;

    //
    // Controls enabling server cluster interactions on a controller. This in turn
    // causes the following to get enabled:
    //
    //  - CASEServer to listen for unsolicited Sigma1 messages.
    //  - Advertisement of active controller operational identities.
    //
    bool enableServerInteractions = false;

    /**
     * Controls whether shutdown of the controller removes the corresponding
     * entry from the in-memory fabric table, but NOT from storage.
     *
     * Note that this means that after controller shutdown the storage and
     * in-memory versions of the fabric table will be out of sync.
     * For compatibility reasons this is the default behavior.
     *
     * @see deleteFromFabricTableOnShutdown
     */
    bool removeFromFabricTableOnShutdown = true;

    /**
     * Controls whether shutdown of the controller deletes the corresponding
     * entry from the fabric table (both in-memory and storage).
     *
     * If both `removeFromFabricTableOnShutdown` and this setting are true,
     * this setting will take precedence.
     *
     * @see removeFromFabricTableOnShutdown
     */
    bool deleteFromFabricTableOnShutdown = false;

    /**
     * Specifies whether to utilize the fabric table entry for the given FabricIndex
     * for initialization. If provided and neither the operational key pair nor the NOC
     * chain are provided, then attempt to locate a fabric corresponding to the given FabricIndex.
     */
    chip::Optional<FabricIndex> fabricIndex;

    Credentials::DeviceAttestationVerifier * deviceAttestationVerifier = nullptr;
    CommissioningDelegate * defaultCommissioner                        = nullptr;
};

// TODO everything other than the fabric storage, group data provider, OperationalKeystore,
// OperationalCertificateStore, SessionKeystore, and SessionResumptionStorage here should
// be removed. We're blocked because of the need to support !CHIP_DEVICE_LAYER
struct FactoryInitParams
{
    System::Layer * systemLayer                                        = nullptr;
    PersistentStorageDelegate * fabricIndependentStorage               = nullptr;
    Credentials::CertificateValidityPolicy * certificateValidityPolicy = nullptr;
    Credentials::GroupDataProvider * groupDataProvider                 = nullptr;
    TimerDelegate * timerDelegate                                      = nullptr;
    Crypto::SessionKeystore * sessionKeystore                          = nullptr;
    Inet::EndPointManager<Inet::TCPEndPoint> * tcpEndPointManager      = nullptr;
    Inet::EndPointManager<Inet::UDPEndPoint> * udpEndPointManager      = nullptr;
    FabricTable * fabricTable                                          = nullptr;
    Crypto::OperationalKeystore * operationalKeystore                  = nullptr;
    Credentials::OperationalCertificateStore * opCertStore             = nullptr;
    SessionResumptionStorage * sessionResumptionStorage                = nullptr;
#if CONFIG_NETWORK_LAYER_BLE
    Ble::BleLayer * bleLayer = nullptr;
#endif
#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
    WiFiPAF::WiFiPAFLayer * wifipaf_layer = nullptr;
#endif

    //
    // Controls enabling server cluster interactions on a controller. This in turn
    // causes the following to get enabled:
    //
    //  - Advertisement of active controller operational identities.
    //
    bool enableServerInteractions = false;

    // Controls whether the controller factory initialization is prevented from
    // overwriting the global DnssdServer's secured port. When running in a
    // combined server/controller app where the server's port is primary, this
    // must be set to true to keep DNS-SD advertising the server's port.
    bool preventDnssdPortOverwrite = false;

    /* The port used for operational communication to listen for and send messages over UDP/TCP.
     * The default value of `0` will pick any available port. */
    uint16_t listenPort = 0;

    // MUST NOT be null during initialization: every application must define the
    // data model it wants to use. Backwards-compatibility can use `CodegenDataModelProviderInstance`
    // for ember/zap-generated models.
    chip::app::DataModel::Provider * dataModelProvider = nullptr;

    std::optional<Inet::InterfaceId> interfaceId;

    // The minimum backoff interval for LIT devices. This is used to calculate the sigma1
    // retransmission timeout for LIT devices, ensuring it's at least `minimumLITBackoffInterval`.
    // Specifically, the timeout is `max(LIT activeRetransTimeout,
    // minimumLITBackoffInterval)`. This prevents issues with MRP retransmission in Thread
    // networks when activeRetransTimeout is too small.
    // Note: Setting this parameter to a nonzero value is not spec-compliant.
    Optional<uint32_t> minimumLITBackoffInterval;
};

class DeviceControllerFactory
{
public:
    static DeviceControllerFactory & GetInstance()
    {
        static DeviceControllerFactory instance;
        return instance;
    }

    CHIP_ERROR Init(FactoryInitParams params);

    // Shuts down matter and frees the system state.
    //
    // Must not be called while any controllers are alive, or while any calls
    // to RetainSystemState or EnsureAndRetainSystemState have not been balanced
    // by a call to ReleaseSystemState.
    void Shutdown();

    CHIP_ERROR SetupController(SetupParams params, DeviceController & controller);
    CHIP_ERROR SetupCommissioner(SetupParams params, DeviceCommissioner & commissioner);

    // ----- IO -----
    /**
     * @brief
     * Start the event loop task within the CHIP stack
     * @return CHIP_ERROR   The return status
     */
    CHIP_ERROR ServiceEvents();

    ~DeviceControllerFactory();
    DeviceControllerFactory(DeviceControllerFactory const &) = delete;
    void operator=(DeviceControllerFactory const &)          = delete;

    //
    // Some clients do not prefer a complete shutdown of the stack being initiated if
    // all device controllers have ceased to exist. To avoid that, this method has been
    // created to permit retention of the underlying system state.
    //
    // Calls to this method must be balanced by calling ReleaseSystemState before Shutdown.
    //
    void RetainSystemState();

    //
    // To initiate shutdown of the stack upon termination of all resident controllers in the
    // system, invoke this method to decrement the refcount on the system state and consequently,
    // shut-down the stack.
    //
    // This should only be invoked if a matching call to RetainSystemState() was called prior.
    //
    // Returns true if stack was shut down in response to this call, or false otherwise.
    //
    bool ReleaseSystemState();

    // Like RetainSystemState(), but will re-initialize the system state first if necessary.
    // Calls to this method must be balanced by calling ReleaseSystemState before Shutdown.
    CHIP_ERROR EnsureAndRetainSystemState();

    //
    // Retrieve a read-only pointer to the system state object that contains pointers to key stack
    // singletons. If the pointer is null, it indicates that the DeviceControllerFactory has yet to
    // be initialized properly, or has already been shut-down.
    //
    // This pointer ceases to be valid after a call to Shutdown has been made, or if all active
    // DeviceController instances have gone to 0. Consequently, care has to be taken to correctly
    // sequence the shutting down of active controllers with any entity that interacts with objects
    // present in the system state object. If de-coupling is desired, RetainSystemState and
    // ReleaseSystemState can be used to avoid this.
    //
    const DeviceControllerSystemState * GetSystemState() const { return mSystemState; }

    class ControllerFabricDelegate final : public chip::FabricTable::Delegate
    {
    public:
        CHIP_ERROR Init(SessionResumptionStorage * sessionResumptionStorage, Credentials::GroupDataProvider * groupDataProvider)
        {
            VerifyOrReturnError(sessionResumptionStorage != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
            VerifyOrReturnError(groupDataProvider != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

            mSessionResumptionStorage = sessionResumptionStorage;
            mGroupDataProvider        = groupDataProvider;
            return CHIP_NO_ERROR;
        };

        void OnFabricRemoved(const chip::FabricTable & fabricTable, FabricIndex fabricIndex) override
        {
            (void) fabricTable;
            if (mGroupDataProvider != nullptr)
            {
                TEMPORARY_RETURN_IGNORED mGroupDataProvider->RemoveFabric(fabricIndex);
            }
            ClearCASEResumptionStateOnFabricChange(fabricIndex);
        };

        void OnFabricUpdated(const chip::FabricTable & fabricTable, chip::FabricIndex fabricIndex) override
        {
            (void) fabricTable;
            ClearCASEResumptionStateOnFabricChange(fabricIndex);
        }

    private:
        void ClearCASEResumptionStateOnFabricChange(chip::FabricIndex fabricIndex)
        {
            VerifyOrReturn(mSessionResumptionStorage != nullptr);
            CHIP_ERROR err = mSessionResumptionStorage->DeleteAll(fabricIndex);
            if (err != CHIP_NO_ERROR)
            {
                ChipLogError(Controller,
                             "Warning, failed to delete session resumption state for fabric index 0x%x: %" CHIP_ERROR_FORMAT,
                             static_cast<unsigned>(fabricIndex), err.Format());
            }
        }

        Credentials::GroupDataProvider * mGroupDataProvider  = nullptr;
        SessionResumptionStorage * mSessionResumptionStorage = nullptr;
    };

private:
    DeviceControllerFactory() {}
    void PopulateInitParams(ControllerInitParams & controllerParams, const SetupParams & params);
    CHIP_ERROR InitSystemState(FactoryInitParams params);
    CHIP_ERROR ReinitSystemStateIfNecessary();
    void ControllerInitialized(const DeviceController & controller);

    uint16_t mListenPort;
    std::optional<Inet::InterfaceId> mInterfaceId;

    DeviceControllerSystemState * mSystemState                          = nullptr;
    PersistentStorageDelegate * mFabricIndependentStorage               = nullptr;
    Crypto::OperationalKeystore * mOperationalKeystore                  = nullptr;
    Credentials::OperationalCertificateStore * mOpCertStore             = nullptr;
    Credentials::CertificateValidityPolicy * mCertificateValidityPolicy = nullptr;
    SessionResumptionStorage * mSessionResumptionStorage                = nullptr;
    app::DataModel::Provider * mDataModelProvider                       = nullptr;
    bool mEnableServerInteractions                                      = false;
    bool mPreventDnssdPortOverwrite                                     = false;
};

} // namespace Controller
} // namespace chip
