/*
 *   Copyright (c) 2020-2022 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.
 *
 */
#pragma once

#include <controller/java/ControllerConfig.h>
#include <lib/support/JniReferences.h>

#include <memory>
#include <vector>

#include <jni.h>

#include <app/icd/client/CheckInHandler.h>
#include <app/icd/client/DefaultICDClientStorage.h>
#include <controller/CHIPDeviceController.h>
#include <controller/java/CHIPP256KeypairBridge.h>
#include <credentials/GroupDataProviderImpl.h>
#include <credentials/PersistentStorageOpCertStore.h>
#include <credentials/attestation_verifier/DacOnlyPartialAttestationVerifier.h>
#include <crypto/RawKeySessionKeystore.h>
#include <lib/support/TimeUtils.h>
#include <platform/internal/DeviceNetworkInfo.h>
#ifdef JAVA_MATTER_CONTROLLER_TEST
#include <controller/ExampleOperationalCredentialsIssuer.h>
#include <controller/ExamplePersistentStorage.h>
#else
#include <platform/android/AndroidChipPlatform-JNI.h>
#endif // JAVA_MATTER_CONTROLLER_TEST

#include "AndroidCheckInDelegate.h"
#include "AndroidOperationalCredentialsIssuer.h"
#include "AttestationTrustStoreBridge.h"
#include "DeviceAttestationDelegateBridge.h"
#if CHIP_DEVICE_CONFIG_DYNAMIC_SERVER
#include "OTAProviderDelegateBridge.h"
#endif

constexpr uint8_t kUserActiveModeTriggerInstructionBufferLen =
    128 + 1; // 128bytes is max UserActiveModeTriggerInstruction size and 1 byte is for escape sequence.

constexpr uint8_t kCountryCodeBufferLen = 2;
/**
 * This class contains all relevant information for the JNI view of CHIPDeviceController
 * to handle all controller-related processing.
 *
 * Generally it contains the DeviceController class itself, plus any related delegates/callbacks.
 */
class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDelegate, public chip::PersistentStorageDelegate
{
public:
    ~AndroidDeviceControllerWrapper();

    chip::Controller::DeviceCommissioner * Controller() { return mController.get(); }
    void SetJavaObjectRef(JavaVM * vm, jobject obj);
    jobject JavaObjectRef() { return mJavaObjectRef.ObjectRef(); }
    jlong ToJNIHandle();

    /**
     * Returns a CHIPP256KeypairBridge which can be used to delegate signing operations
     * to a KeypairDelegate in the Java layer. Note that this will always return a pointer
     * to the same instance, once initialized.
     */
    CHIPP256KeypairBridge * GetP256KeypairBridge()
    {
        if (mKeypairBridge == nullptr)
        {
            mKeypairBridge = chip::Platform::New<CHIPP256KeypairBridge>();
        }
        return mKeypairBridge;
    }

    void CallJavaIntMethod(const char * methodName, jint argument);
    void CallJavaLongMethod(const char * methodName, jlong argument);
    CHIP_ERROR InitializeOperationalCredentialsIssuer();

    /**
     * Convert network credentials from Java, and apply them to the commissioning parameters object.
     */
    CHIP_ERROR ApplyNetworkCredentials(chip::Controller::CommissioningParameters & params, jobject networkCredentials);

    /**
     * Convert ICD Registration Infomations from Java, and apply them to the commissioning parameters object.
     */
    CHIP_ERROR ApplyICDRegistrationInfo(chip::Controller::CommissioningParameters & params, jobject icdRegistrationInfo);

    /**
     * Update the CommissioningParameters used by the active device commissioner
     */
    CHIP_ERROR UpdateCommissioningParameters(const chip::Controller::CommissioningParameters & params);

    // DevicePairingDelegate implementation
    void OnStatusUpdate(chip::Controller::DevicePairingDelegate::Status status) override;
    void OnPairingComplete(CHIP_ERROR error) override;
    void OnPairingDeleted(CHIP_ERROR error) override;
    void OnCommissioningComplete(chip::NodeId deviceId, CHIP_ERROR error) override;
    void OnCommissioningStatusUpdate(chip::PeerId peerId, chip::Controller::CommissioningStage stageCompleted,
                                     CHIP_ERROR error) override;
    void OnCommissioningStageStart(chip::PeerId peerId, chip::Controller::CommissioningStage stage) override;
    void OnReadCommissioningInfo(const chip::Controller::ReadCommissioningInfo & info) override;
    void OnScanNetworksSuccess(
        const chip::app::Clusters::NetworkCommissioning::Commands::ScanNetworksResponse::DecodableType & dataResponse) override;
    void OnScanNetworksFailure(CHIP_ERROR error) override;
    void OnICDRegistrationInfoRequired() override;
    void OnICDRegistrationComplete(chip::ScopedNodeId icdNodeId, uint32_t icdCounter) override;

    // PersistentStorageDelegate implementation
    CHIP_ERROR SyncSetKeyValue(const char * key, const void * value, uint16_t size) override;
    CHIP_ERROR SyncGetKeyValue(const char * key, void * buffer, uint16_t & size) override;
    CHIP_ERROR SyncDeleteKeyValue(const char * key) override;

    chip::Controller::AutoCommissioner * GetAutoCommissioner() { return &mAutoCommissioner; }

    chip::Credentials::PartialDACVerifier * GetPartialDACVerifier() { return &mPartialDACVerifier; }

    const chip::Controller::CommissioningParameters & GetCommissioningParameters() const { return mCommissioningParameter; }

    static AndroidDeviceControllerWrapper * FromJNIHandle(jlong handle)
    {
        return reinterpret_cast<AndroidDeviceControllerWrapper *>(handle);
    }

#ifdef JAVA_MATTER_CONTROLLER_TEST
    using ExampleOperationalCredentialsIssuerPtr = std::unique_ptr<chip::Controller::ExampleOperationalCredentialsIssuer>;
#else
    using AndroidOperationalCredentialsIssuerPtr = std::unique_ptr<chip::Controller::AndroidOperationalCredentialsIssuer>;
#endif

    /**
     * Initializes a new CHIPDeviceController using the given parameters, and returns a pointer to the
     * AndroidDeviceControllerWrapper that holds the underlying controller.
     *
     * If the keypairDelegate is provided, then the rootCertificate, nodeOperationalCertificate, and
     * ipkEpochKey must also be specified. If no operational credentials are specified here, then an
     * ephemeral signing configuration will be generated for you.
     *
     * If there are any errors during the initialization of this controller, then a nullptr will be
     * returned.
     *
     * @param[in] vm the JavaVM
     * @param[in] deviceControllerObj a reference to the Java ChipDeviceController
     * @param[in] nodeId the local node ID to use for this controller instance
     * @param[in] cats the set of CASE authenticated tags
     * @param[in] systemLayer a pointer to the System::Layer instance
     * @param[in] tcpEndpointManager a pointer to a Inet::EndPointManager for TCP connections
     * @param[in] udpEndpointManager a pointer to a Inet::EndPointManager for UDP connections
     * @param[in] opCredsIssuer a pointer to an issuer for Android operational credentials
     * @param[in] keypairDelegate a pointer to a Java KeypairDelegate implementation.
     * @param[in] rootCertificate an X.509 DER-encoded trusted root certificate for this node
     * @param[in] intermediateCertificate an X.509 DER-encoded intermediate certificate for this node
     * @param[in] nodeOperationalCertificate an X.509 DER-encoded operational certificate for this node
     * @param[in] ipkEpochKey the IPK epoch key to use for this node
     * @param[in] listenPort the UDP port to listen on
     * @param[in] controllerVendorId the vendor ID identifying the controller
     * @param[in] failsafeTimerSeconds the failsafe timer in seconds
     * @param[in] attemptNetworkScanWiFi whether to attempt a network scan when configuring the network for a WiFi device
     * @param[in] attemptNetworkScanThread whether to attempt a network scan when configuring the network for a Thread device
     * @param[in] skipCommissioningComplete whether to skip the CASE commissioningComplete command during commissioning
     * @param[out] errInfoOnFailure a pointer to a CHIP_ERROR that will be populated if this method returns nullptr
     */
    static AndroidDeviceControllerWrapper *
    AllocateNew(JavaVM * vm, jobject deviceControllerObj, chip::NodeId nodeId, chip::FabricId fabricId,
                const chip::CATValues & cats, chip::System::Layer * systemLayer,
                chip::Inet::EndPointManager<chip::Inet::TCPEndPoint> * tcpEndPointManager,
                chip::Inet::EndPointManager<chip::Inet::UDPEndPoint> * udpEndPointManager,
#ifdef JAVA_MATTER_CONTROLLER_TEST
                ExampleOperationalCredentialsIssuerPtr opCredsIssuer,
#else
                AndroidOperationalCredentialsIssuerPtr opCredsIssuer,
#endif
                jobject keypairDelegate, jbyteArray rootCertificate, jbyteArray intermediateCertificate,
                jbyteArray nodeOperationalCertificate, jbyteArray ipkEpochKey, uint16_t listenPort, uint16_t controllerVendorId,
                uint16_t failsafeTimerSeconds, bool attemptNetworkScanWiFi, bool attemptNetworkScanThread,
                bool skipCommissioningComplete, bool skipAttestationCertificateValidation, jstring countryCode,
                bool enableServerInteractions, CHIP_ERROR * errInfoOnFailure);

    void Shutdown();

#ifdef JAVA_MATTER_CONTROLLER_TEST
    chip::Controller::ExampleOperationalCredentialsIssuer * GetAndroidOperationalCredentialsIssuer()
#else
    chip::Controller::AndroidOperationalCredentialsIssuer * GetAndroidOperationalCredentialsIssuer()
#endif
    {
        return mOpCredsIssuer.get();
    }

    DeviceAttestationDelegateBridge * GetDeviceAttestationDelegateBridge() { return mDeviceAttestationDelegateBridge; }

    CHIP_ERROR UpdateDeviceAttestationDelegateBridge(jobject deviceAttestationDelegate, chip::Optional<uint16_t> expiryTimeoutSecs,
                                                     bool shouldWaitAfterDeviceAttestation);

    CHIP_ERROR UpdateAttestationTrustStoreBridge(jobject attestationTrustStoreDelegate, jobject cdTrustKeys);

    CHIP_ERROR StartOTAProvider(jobject otaProviderDelegate);

    CHIP_ERROR FinishOTAProvider();

    CHIP_ERROR SetICDCheckInDelegate(jobject checkInDelegate);

    void StartDnssd();

    void StopDnssd();

private:
    using ChipDeviceControllerPtr = std::unique_ptr<chip::Controller::DeviceCommissioner>;

    ChipDeviceControllerPtr mController;

    // TODO: This may need to be injected as a GroupDataProvider*
    chip::Credentials::GroupDataProviderImpl mGroupDataProvider;
    // TODO: This may need to be injected as an OperationalCertificateStore *
    chip::Credentials::PersistentStorageOpCertStore mOpCertStore;
    // TODO: This may need to be injected as a SessionKeystore*
    chip::Crypto::RawKeySessionKeystore mSessionKeystore;

    chip::app::AndroidCheckInDelegate mCheckInDelegate;
    chip::app::CheckInHandler mCheckInHandler;

    JavaVM * mJavaVM = nullptr;
    chip::JniGlobalReference mJavaObjectRef;
    CHIPP256KeypairBridge * mKeypairBridge = nullptr;
#ifdef JAVA_MATTER_CONTROLLER_TEST
    ExampleOperationalCredentialsIssuerPtr mOpCredsIssuer;
    PersistentStorage mExampleStorage;
#else
    AndroidOperationalCredentialsIssuerPtr mOpCredsIssuer;
#endif // JAVA_MATTER_CONTROLLER_TEST

    // These fields allow us to release the string/byte array memory later.
    jstring ssidStr                    = nullptr;
    jstring passwordStr                = nullptr;
    const char * ssid                  = nullptr;
    const char * password              = nullptr;
    jbyteArray operationalDatasetBytes = nullptr;
    jbyte * operationalDataset         = nullptr;

    std::vector<uint8_t> mNocCertificate;
    std::vector<uint8_t> mIcacCertificate;
    std::vector<uint8_t> mRcacCertificate;

    char mCountryCode[kCountryCodeBufferLen];

    chip::Controller::AutoCommissioner mAutoCommissioner;

    chip::Credentials::PartialDACVerifier mPartialDACVerifier;

    DeviceAttestationDelegateBridge * mDeviceAttestationDelegateBridge        = nullptr;
    AttestationTrustStoreBridge * mAttestationTrustStoreBridge                = nullptr;
    chip::Credentials::DeviceAttestationVerifier * mDeviceAttestationVerifier = nullptr;
#if CHIP_DEVICE_CONFIG_DYNAMIC_SERVER
    OTAProviderDelegateBridge * mOtaProviderBridge = nullptr;
#endif
    bool mDeviceIsICD = false;
    uint8_t mICDSymmetricKey[chip::Crypto::kAES_CCM128_Key_Length];
    char mUserActiveModeTriggerInstructionBuffer[kUserActiveModeTriggerInstructionBufferLen];
    chip::MutableCharSpan mUserActiveModeTriggerInstruction = chip::MutableCharSpan(mUserActiveModeTriggerInstructionBuffer);
    chip::BitMask<chip::app::Clusters::IcdManagement::UserActiveModeTriggerBitmap> mUserActiveModeTriggerHint;

    uint32_t mIdleModeDuration    = 0;
    uint32_t mActiveModeDuration  = 0;
    uint16_t mActiveModeThreshold = 0;
    chip::Controller::CommissioningParameters mCommissioningParameter;
    bool mIsInitialized = false;
    AndroidDeviceControllerWrapper(ChipDeviceControllerPtr controller,
#ifdef JAVA_MATTER_CONTROLLER_TEST
                                   ExampleOperationalCredentialsIssuerPtr opCredsIssuer
#else
                                   AndroidOperationalCredentialsIssuerPtr opCredsIssuer
#endif
                                   ) :
        mController(std::move(controller)),
        mOpCredsIssuer(std::move(opCredsIssuer))
    {}
};

inline jlong AndroidDeviceControllerWrapper::ToJNIHandle()
{
    static_assert(sizeof(jlong) >= sizeof(void *), "Need to store a pointer in a java handle");
    return reinterpret_cast<jlong>(this);
}
