/*
 *
 *    Copyright (c) 2023 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 <lib/core/Optional.h>
#include <lib/support/ScopedBuffer.h>
#include <lib/support/Span.h>

namespace chip {

#define CHIP_ERROR_TLV_PROCESSOR(e)                                                                                                \
    ChipError(ChipError::Range::kLastRange, ((uint8_t) ChipError::Range::kLastRange << 3) | e, __FILE__, __LINE__)

#define CHIP_OTA_TLV_CONTINUE_PROCESSING CHIP_ERROR_TLV_PROCESSOR(0x01)
#define CHIP_OTA_CHANGE_PROCESSOR CHIP_ERROR_TLV_PROCESSOR(0x02)
#define CHIP_OTA_PROCESSOR_NOT_REGISTERED CHIP_ERROR_TLV_PROCESSOR(0x03)
#define CHIP_OTA_PROCESSOR_ALREADY_REGISTERED CHIP_ERROR_TLV_PROCESSOR(0x04)
#define CHIP_OTA_PROCESSOR_CLIENT_INIT CHIP_ERROR_TLV_PROCESSOR(0x05)
#define CHIP_OTA_PROCESSOR_MAKE_ROOM CHIP_ERROR_TLV_PROCESSOR(0x06)
#define CHIP_OTA_PROCESSOR_PUSH_CHUNK CHIP_ERROR_TLV_PROCESSOR(0x07)
#define CHIP_OTA_PROCESSOR_IMG_AUTH CHIP_ERROR_TLV_PROCESSOR(0x08)
#define CHIP_OTA_FETCH_ALREADY_SCHEDULED CHIP_ERROR_TLV_PROCESSOR(0x09)
#define CHIP_OTA_PROCESSOR_IMG_COMMIT CHIP_ERROR_TLV_PROCESSOR(0x0A)
#define CHIP_OTA_PROCESSOR_CB_NOT_REGISTERED CHIP_ERROR_TLV_PROCESSOR(0x0B)
#define CHIP_OTA_PROCESSOR_EEPROM_OFFSET CHIP_ERROR_TLV_PROCESSOR(0x0C)
#define CHIP_OTA_PROCESSOR_EXTERNAL_STORAGE CHIP_ERROR_TLV_PROCESSOR(0x0D)
#define CHIP_OTA_PROCESSOR_START_IMAGE CHIP_ERROR_TLV_PROCESSOR(0x0E)
#define SL_GENERIC_OTA_ERROR CHIP_ERROR_TLV_PROCESSOR(0x0E)

// Descriptor constants
inline constexpr size_t kVersionStringSize = 64;
inline constexpr size_t kBuildDateSize     = 64;

/**
 * Used alongside RegisterDescriptorCallback to register
 * a custom descriptor processing function with a certain
 * TLV processor.
 */
typedef CHIP_ERROR (*ProcessDescriptor)(void * descriptor);

struct OTATlvHeader
{
    uint32_t tag;
    uint32_t length;
};

/**
 * This class defines an interface for a Matter TLV processor.
 * Instances of derived classes can be registered as processors
 * in OTAMultiImageProcessorImpl. Based on the TLV type, a certain
 * processor is used to process subsequent blocks until the number
 * of bytes found in the metadata is processed. In case a block contains
 * data from two different TLVs, the processor should ensure the remaining
 * data is returned in the block passed as input.
 * The default processors: application, SSBL and factory data are registered
 * in OTAMultiImageProcessorImpl::Init through OtaHookInit.
 * Applications should use OTAMultiImageProcessorImpl::RegisterProcessor
 * to register additional processors.
 */
class OTATlvProcessor
{
public:
    virtual ~OTATlvProcessor() {}

    virtual CHIP_ERROR Init()           = 0;
    virtual CHIP_ERROR Clear()          = 0;
    virtual CHIP_ERROR ApplyAction()    = 0;
    virtual CHIP_ERROR FinalizeAction() = 0;
    virtual CHIP_ERROR ExitAction() { return CHIP_NO_ERROR; }

    CHIP_ERROR Process(ByteSpan & block);
    void RegisterDescriptorCallback(ProcessDescriptor callback) { mCallbackProcessDescriptor = callback; }
    void SetLength(uint32_t length) { mLength = length; }
    void SetWasSelected(bool selected) { mWasSelected = selected; }
    bool WasSelected() { return mWasSelected; }
#if OTA_ENCRYPTION_ENABLE
    CHIP_ERROR vOtaProcessInternalEncryption(MutableByteSpan & block);
#endif

protected:
    /**
     * @brief Process custom TLV payload
     *
     * The method takes subsequent chunks of the Matter OTA image file and processes them.
     * If more image chunks are needed, CHIP_ERROR_BUFFER_TOO_SMALL error is returned.
     * Other error codes indicate that an error occurred during processing. Fetching
     * next data is scheduled automatically by OTAMultiImageProcessorImpl if the return value
     * is neither an error code, nor CHIP_OTA_FETCH_ALREADY_SCHEDULED (which implies the
     * scheduling is done inside ProcessInternal or will be done in the future, through a
     * callback).
     *
     * @param block Byte span containing a subsequent Matter OTA image chunk. When the method
     *              returns CHIP_NO_ERROR, the byte span is used to return a remaining part
     *              of the chunk, not used by current TLV processor.
     *
     * @retval CHIP_NO_ERROR                    Block was processed successfully.
     * @retval CHIP_ERROR_BUFFER_TOO_SMALL      Provided buffers are insufficient to decode some
     *                                          metadata (e.g. a descriptor).
     * @retval CHIP_OTA_FETCH_ALREADY_SCHEDULED Should be returned if ProcessInternal schedules
     *                                          fetching next data (e.g. through a callback).
     * @retval Error code                       Something went wrong. Current OTA process will be
     *                                          canceled.
     */
    virtual CHIP_ERROR ProcessInternal(ByteSpan & block) = 0;

    void ClearInternal();

    bool IsError(CHIP_ERROR & status);

#if OTA_ENCRYPTION_ENABLE
    /*ota decryption*/
    uint32_t mIVOffset = 0;
    /* Expected byte size of the OTAEncryptionKeyLength */
    static constexpr size_t kOTAEncryptionKeyLength = 16;
#endif
    uint32_t mLength                             = 0;
    uint32_t mProcessedLength                    = 0;
    bool mWasSelected                            = false;
    ProcessDescriptor mCallbackProcessDescriptor = nullptr;
};

/**
 * This class can be used to accumulate data until a given threshold.
 * Should be used by OTATlvProcessor derived classes if they need
 * metadata accumulation (e.g. for custom header decoding).
 */
class OTADataAccumulator
{
public:
    void Init(uint32_t threshold);
    void Clear();
    CHIP_ERROR Accumulate(ByteSpan & block);

    inline uint8_t * data() { return mBuffer.Get(); }
    inline uint32_t GetThreshold() { return mThreshold; }

private:
    uint32_t mThreshold;
    uint32_t mBufferOffset;
    Platform::ScopedMemoryBuffer<uint8_t> mBuffer;
};

} // namespace chip
