/*
 *   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 <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>
#include <platform/android/CHIPP256KeypairBridge.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();

#ifndef JAVA_MATTER_CONTROLLER_TEST
    /**
     * 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;
    }
#endif // JAVA_MATTER_CONTROLLER_TEST

    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 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;
#ifdef JAVA_MATTER_CONTROLLER_TEST
    ExampleOperationalCredentialsIssuerPtr mOpCredsIssuer;
    PersistentStorage mExampleStorage;
#else
    AndroidOperationalCredentialsIssuerPtr mOpCredsIssuer;
    CHIPP256KeypairBridge * mKeypairBridge = nullptr;
#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;

    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);
}
