/*
 *
 *    Copyright (c) 2021 Project CHIP Authors
 *
 *    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
 *          Provides an implementation of the DiagnosticDataProvider object
 *          for android platform.
 */

#include <cstddef>
#include <cstring>
#include <jni.h>
#include <platform/internal/CHIPDeviceLayerInternal.h>

#include "DiagnosticDataProviderImpl.h"
#include <lib/support/CHIPJNIError.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/CHIPMemString.h>
#include <lib/support/JniTypeWrappers.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/DiagnosticDataProvider.h>
#include <unistd.h>

using namespace ::chip::app::Clusters::GeneralDiagnostics;

namespace chip {
namespace DeviceLayer {

DiagnosticDataProviderImpl & DiagnosticDataProviderImpl::GetDefaultInstance()
{
    static DiagnosticDataProviderImpl sInstance;
    return sInstance;
}

void DiagnosticDataProviderImpl::InitializeWithObject(jobject manager)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    VerifyOrReturn(env != nullptr,
                   ChipLogError(DeviceLayer, "Failed to GetEnvForCurrentThread for DiagnosticDataProviderManagerImpl"));

    VerifyOrReturn(mDiagnosticDataProviderManagerObject.Init(manager) == CHIP_NO_ERROR,
                   ChipLogError(DeviceLayer, "Failed to Init DiagnosticDataProviderManager"));

    jclass DiagnosticDataProviderManagerClass = env->GetObjectClass(manager);
    VerifyOrReturn(DiagnosticDataProviderManagerClass != nullptr,
                   ChipLogError(DeviceLayer, "Failed to get DiagnosticDataProviderManager Java class"));

    mGetRebootCountMethod = env->GetMethodID(DiagnosticDataProviderManagerClass, "getRebootCount", "()I");
    if (mGetRebootCountMethod == nullptr)
    {
        ChipLogError(DeviceLayer, "Failed to access DiagnosticDataProviderManager 'getRebootCount' method");
        env->ExceptionClear();
    }

    mGetNifMethod =
        env->GetMethodID(DiagnosticDataProviderManagerClass, "getNetworkInterfaces", "()[Lchip/platform/NetworkInterface;");
    if (mGetNifMethod == nullptr)
    {
        ChipLogError(DeviceLayer, "Failed to access DiagnosticDataProviderManager 'getNetworkInterfaces' method");
        env->ExceptionClear();
    }
}

CHIP_ERROR DiagnosticDataProviderImpl::GetRebootCount(uint16_t & rebootCount)
{
    chip::DeviceLayer::StackUnlock unlock;
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    VerifyOrReturnLogError(mDiagnosticDataProviderManagerObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE);
    VerifyOrReturnLogError(mGetRebootCountMethod != nullptr, CHIP_ERROR_INCORRECT_STATE);
    VerifyOrReturnLogError(env != nullptr, CHIP_JNI_ERROR_NO_ENV);
    ChipLogProgress(DeviceLayer, "Received GetRebootCount");

    jint count = env->CallIntMethod(mDiagnosticDataProviderManagerObject.ObjectRef(), mGetRebootCountMethod);
    VerifyOrReturnLogError(count < UINT16_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE);
    rebootCount = static_cast<uint16_t>(count);

    return CHIP_NO_ERROR;
}

CHIP_ERROR DiagnosticDataProviderImpl::GetNetworkInterfaces(NetworkInterface ** netifpp)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    VerifyOrReturnError(env != nullptr, CHIP_JNI_ERROR_NULL_OBJECT,
                        ChipLogError(DeviceLayer, "Could not get JNIEnv for current thread"));
    JniLocalReferenceScope scope(env);
    VerifyOrExit(mDiagnosticDataProviderManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE);
    VerifyOrExit(mGetNifMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    {
        ChipLogProgress(DeviceLayer, "Received GetNetworkInterfaces");
        jobjectArray nifList =
            (jobjectArray) env->CallObjectMethod(mDiagnosticDataProviderManagerObject.ObjectRef(), mGetNifMethod);
        if (env->ExceptionCheck())
        {
            ChipLogError(DeviceLayer, "Java exception in DiagnosticDataProviderImpl::GetNetworkInterfaces");
            env->ExceptionDescribe();
            env->ExceptionClear();
            return CHIP_ERROR_INCORRECT_STATE;
        }
        jint length = env->GetArrayLength(nifList);

        NetworkInterface * head = nullptr;
        for (jint i = 0; i < length; i++)
        {
            NetworkInterface * ifp = new NetworkInterface();

            jobject nifObject = env->GetObjectArrayElement(nifList, i);
            jclass nifClass   = env->GetObjectClass(nifObject);

            jfieldID getNameField = env->GetFieldID(nifClass, "name", "Ljava/lang/String;");
            jstring jname         = static_cast<jstring>(env->GetObjectField(nifObject, getNameField));
            if (jname != nullptr)
            {
                JniUtfString name(env, jname);
                Platform::CopyString(ifp->Name, name.c_str());
                ifp->Name[Inet::InterfaceId::kMaxIfNameLength - 1] = '\0';
                ifp->name                                          = CharSpan(ifp->Name, strlen(ifp->Name));
            }

            jfieldID isOperationalField = env->GetFieldID(nifClass, "isOperational", "Z");
            ifp->isOperational          = static_cast<bool>(env->GetBooleanField(nifObject, isOperationalField));

            jfieldID getOpsrIPV4Field = env->GetFieldID(nifClass, "offPremiseServicesReachableIPv4", "Ljava/lang/Boolean;");
            jobject opsrIPV4Obj       = env->GetObjectField(nifObject, getOpsrIPV4Field);
            if (opsrIPV4Obj == nullptr)
            {
                ifp->offPremiseServicesReachableIPv4.SetNull();
            }
            else
            {
                jboolean opsrIPV4 = JniReferences::GetInstance().BooleanToPrimitive(opsrIPV4Obj);
                ifp->offPremiseServicesReachableIPv4.SetNonNull(static_cast<bool>(opsrIPV4));
            }

            jfieldID getOpsrIPV6Field = env->GetFieldID(nifClass, "offPremiseServicesReachableIPv6", "Ljava/lang/Boolean;");
            jobject opsrIPV6Obj       = env->GetObjectField(nifObject, getOpsrIPV6Field);
            if (opsrIPV6Obj == nullptr)
            {
                ifp->offPremiseServicesReachableIPv6.SetNull();
            }
            else
            {
                jboolean opsrIPV6 = JniReferences::GetInstance().BooleanToPrimitive(opsrIPV6Obj);
                ifp->offPremiseServicesReachableIPv6.SetNonNull(static_cast<bool>(opsrIPV6));
            }

            jfieldID gethardwareAddressField = env->GetFieldID(nifClass, "hardwareAddress", "[B");
            jbyteArray jHardwareAddressObj   = static_cast<jbyteArray>(env->GetObjectField(nifObject, gethardwareAddressField));
            if (jHardwareAddressObj != nullptr)
            {
                size_t len = env->GetArrayLength(jHardwareAddressObj);
                len        = (len > kMaxHardwareAddrSize) ? kMaxHardwareAddrSize : len;
                env->GetByteArrayRegion(jHardwareAddressObj, 0, static_cast<uint32_t>(len),
                                        reinterpret_cast<jbyte *>(ifp->MacAddress));
                ifp->hardwareAddress = ByteSpan(ifp->MacAddress, 6);
            }

            jfieldID getTypeField = env->GetFieldID(nifClass, "type", "I");
            ifp->type             = static_cast<InterfaceTypeEnum>(env->GetIntField(nifObject, getTypeField));

            jfieldID ipv4AddressField  = env->GetFieldID(nifClass, "ipv4Address", "[B");
            jbyteArray jIpv4AddressObj = static_cast<jbyteArray>(env->GetObjectField(nifObject, ipv4AddressField));
            if (jIpv4AddressObj != nullptr)
            {
                JniByteArray Ipv4ByteArray(env, jIpv4AddressObj);

                if (Ipv4ByteArray.size() == kMaxIPv4AddrSize)
                {
                    memcpy(ifp->Ipv4AddressesBuffer[0], reinterpret_cast<const uint8_t *>(Ipv4ByteArray.data()), kMaxIPv4AddrSize);
                    ifp->Ipv4AddressSpans[0] = ByteSpan(ifp->Ipv4AddressesBuffer[0], kMaxIPv4AddrSize);
                    ifp->IPv4Addresses       = chip::app::DataModel::List<chip::ByteSpan>(ifp->Ipv4AddressSpans, 1);
                }
                else
                {
                    ChipLogError(DeviceLayer, "ipv4Address size (%d) not equal to kMaxIPv4AddrSize", Ipv4ByteArray.size());
                }
            }

            jfieldID ipv6AddressField  = env->GetFieldID(nifClass, "ipv6Address", "[B");
            jbyteArray jIpv6AddressObj = static_cast<jbyteArray>(env->GetObjectField(nifObject, ipv6AddressField));
            if (jIpv6AddressObj != nullptr)
            {
                JniByteArray Ipv6ByteArray(env, jIpv6AddressObj);

                if (Ipv6ByteArray.size() == kMaxIPv6AddrSize)
                {
                    memcpy(ifp->Ipv6AddressesBuffer[0], reinterpret_cast<const uint8_t *>(Ipv6ByteArray.data()), kMaxIPv6AddrSize);
                    ifp->Ipv6AddressSpans[0] = ByteSpan(ifp->Ipv6AddressesBuffer[0], kMaxIPv6AddrSize);
                    ifp->IPv6Addresses       = chip::app::DataModel::List<chip::ByteSpan>(ifp->Ipv6AddressSpans, 1);
                }
                else
                {
                    ChipLogError(DeviceLayer, "ipv6Address size (%d) not equal to kMaxIPv6AddrSize", Ipv6ByteArray.size());
                }
            }

            ifp->Next = head;
            head      = ifp;
        }
        *netifpp = head;
    }

exit:
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(Zcl, "ChannelManager::getChannelList status error: %s", err.AsString());
    }
    return err;
}

void DiagnosticDataProviderImpl::ReleaseNetworkInterfaces(NetworkInterface * netifp)
{
    while (netifp)
    {
        NetworkInterface * del = netifp;
        netifp                 = netifp->Next;
        delete del;
    }
}

DiagnosticDataProvider & GetDiagnosticDataProviderImpl()
{
    return DiagnosticDataProviderImpl::GetDefaultInstance();
}

} // namespace DeviceLayer
} // namespace chip
