/*
 * Copyright (C) Jan 2013 Mellanox Technologies Ltd. All rights reserved.
 * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "fw_ops.h"
#include "aux_tlv_ops.h"
#include "fw_comps_mgr/fw_comps_mgr.h"
#include "fw_comps_mgr/fw_comps_mgr_dma_access.h"
#include "tools_layouts/image_layout_layouts.h"

class FsCtrlOperations : public FwOperations
{
public:
    FsCtrlOperations(FwCompsMgr* fwComps) :
        FwOperations((FBase*)NULL), _fwCompsAccess(fwComps), _isSecured(false), _hwDevId(0)
    {
        memset(&_fsCtrlImgInfo, 0, sizeof(_fsCtrlImgInfo));
    }

    virtual ~FsCtrlOperations();

    virtual u_int8_t FwType();

    virtual bool FwQuery(fw_info_t* fwInfo,
                         bool readRom = true,
                         bool isStripedImage = false,
                         bool quickQuery = true,
                         bool ignoreDToc = false,
                         bool verbose = false);
    virtual bool FwVerify(VerifyCallBack verifyCallBackFunc,
                          bool isStripedImage = false,
                          bool showItoc = false,
                          bool ignoreDToc = false); // Add callback print
    virtual bool FwVerifyAdv(ExtVerifyParams& verifyParams);
    // on call of FwReadData with Null image we get image_size
    virtual bool FwReadData(void* image, u_int32_t* image_sizes, bool verbose = false);
    virtual bool FwReadBlock(u_int32_t addr, u_int32_t size, std::vector<u_int8_t>& dataVec);

    virtual bool FwReadRom(std::vector<u_int8_t>& romSect);
    virtual bool FwBurnRom(FImage* romImg,
                           bool ignoreProdIdCheck = false,
                           bool ignoreDevidCheck = false,
                           ProgressCallBack progressFunc = (ProgressCallBack)NULL); // can also read the rom from flint
                                                                                    // and give a vector of u_int8_t
    virtual bool FwDeleteRom(bool ignoreProdIdCheck, ProgressCallBack progressFunc = (ProgressCallBack)NULL);

    virtual bool
      FwBurn(FwOperations* imageOps, u_int8_t forceVersion, ProgressCallBack progressFunc = (ProgressCallBack)NULL);
    virtual bool FwBurnAdvanced(FwOperations* imageOps, ExtBurnParams& burnParams);
    virtual bool FwBurnAdvanced(std::vector<u_int8_t> imageOps4MData,
                                ExtBurnParams& burnParams,
                                FwComponent::comps_ids_t ComponentId = FwComponent::COMPID_BOOT_IMG);
    virtual bool FwBurnBlock(FwOperations* imageOps,
                             ProgressCallBack progressFunc); // Add: callback progress, question arr, callback question,
                                                             // configurations
    bool FwWriteBlock(u_int32_t addr,
                      std::vector<u_int8_t> dataVec,
                      ProgressCallBack progressFunc = (ProgressCallBack)NULL);

    virtual bool FwSetGuids(sg_params_t& sgParam,
                            PrintCallBack callBackFunc = (PrintCallBack)NULL,
                            ProgressCallBack progressFunc = (ProgressCallBack)NULL);

    virtual bool FwSetMFG(fs3_uid_t baseGuid, PrintCallBack callBackFunc = (PrintCallBack)NULL);
    virtual bool FwSetMFG(guid_t baseGuid, PrintCallBack callBackFunc = (PrintCallBack)NULL);
    // use progressFunc when dealing with FS2 image and printFunc when dealing with FS3 image.
    virtual bool FwSetVSD(char* vsdStr,
                          ProgressCallBack progressFunc = (ProgressCallBack)NULL,
                          PrintCallBack printFunc = (PrintCallBack)NULL);
    virtual bool FwSetVPD(char* vpdFileStr, PrintCallBack callBackFunc = (PrintCallBack)NULL);
    virtual bool FwSetAccessKey(hw_key_t userKey, ProgressCallBack progressFunc = (ProgressCallBack)NULL);
    virtual bool FwGetSection(u_int32_t sectType, std::vector<u_int8_t>& sectInfo, bool stripedImage = false);
    virtual bool FwResetNvData();
    virtual bool FwShiftDevData(PrintCallBack progressFunc = (PrintCallBack)NULL);
    virtual const char* FwGetResetRecommandationStr();

    virtual bool FwInit();
    virtual bool FwCalcMD5(u_int8_t md5sum[16]);
    virtual bool FwSetTimeStamp(struct tools_open_ts_entry& timestamp, struct tools_open_fw_version& fwVer);
    virtual bool FwQueryTimeStamp(struct tools_open_ts_entry& timestamp,
                                  struct tools_open_fw_version& fwVer,
                                  bool queryRunning = false);
    virtual bool FwResetTimeStamp();
    virtual u_int32_t GetHwDevId() { return _hwDevId; }
    bool FwReactivateImage();
    Tlv_Status_t GetTsObj(TimeStampIFC** tsObj);
    bool isEncrypted(bool& is_encrypted);
    bool getITOCAddr(u_int32_t& addr);
    bool CheckITOCSignature(u_int8_t* signature);
    bool burnEncryptedImage(FwOperations* imageOps, ExtBurnParams& burnParams);

    virtual bool IsFsCtrlOperations() { return true; }
    virtual mfile* getMfileObj() { return _fwCompsAccess->getMfileObj(); }
    virtual bool IsSecureBootSupported();
    virtual bool IsCableQuerySupported();
    virtual bool IsLifeCycleSupported();
    virtual bool IsEncryptionSupported();
    virtual bool IsSecurityVersionViolated(u_int32_t image_security_version);

protected:
    bool FsIntQuery();
    bool GetImageInfo(u_int8_t* buff);
    bool ReadBootImage(void* image,
                       u_int32_t* image_size,
                       ProgressCallBackAdvSt* stProgressFunc = (ProgressCallBackAdvSt*)NULL);

    bool unsupportedOperation();
    int FwCompsErrToFwOpsErr(fw_comps_error_t err);
    virtual bool VerifyAllowedParams(ExtBurnParams& burnParams, bool isSecure);
    bool BadParamErrMsg(const char* unSupportedOperation, bool isSecure);
    bool _Burn(std::vector<u_int8_t> imageOps4MData,
               ExtBurnParams& burnParams,
               FwComponent::comps_ids_t ComponentId = FwComponent::COMPID_BOOT_IMG);
    bool _createImageOps(FwOperations** imgOps);
    void ExtractSwitchFWVersion(const fwInfoT& fwQuery);

    fs3_info_t _fsCtrlImgInfo;
    FwCompsMgr* _fwCompsAccess;
    bool _isSecured;
    u_int32_t _hwDevId;
};
