/*
 *   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::NodeId 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);

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