#ifndef __OTX_FLASH_BinFileDownloader_HPP__
#define __OTX_FLASH_BinFileDownloader_HPP__

#include "ECUFlasher.hpp"
#include <vector>
#include <mutex>
#include "ECUFlasher.hpp"
#include "asam/mcd/MCDResponseParameter.hpp"
#include "asam/mcd/MCDValue.hpp"
#include "asam/mcd/MCDEventHandler.hpp"
#include "otx/OTXBasicTypes.hpp"
#include "MCDCmdTrans.hpp"
#include "MCDCmdBoardcast.hpp"

namespace otx{
namespace flash{
/**
 * @brief 描述ECU刷写器的基本行为准则。
 *
 */
class BinFileDownloader : virtual public asam::mcd::MCDEventHandler {
public:
	BinFileDownloader();
	BinFileDownloader(const BinFileDownloader&right) = default;
	BinFileDownloader&operator=(const BinFileDownloader&right) = default;

public:
  virtual ~BinFileDownloader() = default;

private:
  ECUFlasher *mFlasher;
  File *mEcuFile;
  ECU *mECU;
  int mErrorCode;
  std::string mMessage;
  MCDCmdTrans *cmdTrans;

  bool transferFile(string filepath, uint64_t nDataLength, int32_t nFrameSize);

public:
  virtual bool downloadFile(ECU *ecu, File *ecuFile);
  virtual ECUFlasher *getFlasher();
  virtual void setFlasher(ECUFlasher *flasher);
  virtual int getErrorCode();
  virtual std::string getMessage();
  void delay(int ms);

private:
  void printResponseParameter(asam::mcd::MCDResponseParameter *param, int level);
  void printValue(asam::A_ASCIISTRING &pname, asam::mcd::MCDValue &pvalue);
  void printLevel(int level);


public:
  virtual void onConfigurationRecordLoaded(asam::d::MCDConfigurationRecord &configurationRecord) override;
  virtual void onDefinableDynIdListChanged(asam::mcd::MCDValues &dynIdList, asam::mcd::MCDLogicalLink &link) override;
  virtual void onFirstEvent() override;
  virtual void onInterfaceError(asam::d::MCDInterface &carinterface, asam::mcd::MCDError &error) override;
  virtual void onInterfacesChanged() override;
  virtual void onInterfaceStatusChanged(asam::d::MCDInterface &carinterface, asam::d::MCDInterfaceStatus status) override;
  virtual void onLastEvent() override;
  virtual void onLinkActivityStateIdle(asam::mcd::MCDLogicalLink &link, asam::mcd::MCDLogicalLinkState linkstate) override;
  virtual void onLinkActivityStateRunning(asam::mcd::MCDLogicalLink &link, asam::mcd::MCDLogicalLinkState linkstate) override;
  virtual void onLinkActivityStateSuspended(asam::mcd::MCDLogicalLink &link, asam::mcd::MCDLogicalLinkState linkstate) override;
  virtual void onLinkError(asam::mcd::MCDLogicalLink &link, asam::mcd::MCDError &error) override;
  virtual void onLinkOneVariantIdentified(asam::mcd::MCDLogicalLink &link, asam::mcd::MCDLogicalLinkState linkstate) override;
  virtual void onLinkOneVariantSelected(asam::mcd::MCDLogicalLink &link, asam::mcd::MCDLogicalLinkState linkstate) override;
  virtual void onLinkQueueCleared(asam::mcd::MCDLogicalLink &link, asam::mcd::MCDLogicalLinkState linkstate) override;
  virtual void onLinkStateCommunication(asam::mcd::MCDLogicalLink &link) override;
  virtual void onLinkStateCreated(asam::mcd::MCDLogicalLink &link) override;
  virtual void onLinkStateOffline(asam::mcd::MCDLogicalLink &link) override;
  virtual void onLinkStateOnline(asam::mcd::MCDLogicalLink &link) override;
  virtual void onLinkVariantIdentified(asam::mcd::MCDLogicalLink &link, asam::mcd::MCDLogicalLinkState linkstate) override;
  virtual void onLinkVariantSelected(asam::mcd::MCDLogicalLink &link, asam::mcd::MCDLogicalLinkState linkstate) override;
  virtual void onLinkVariantSet(asam::mcd::MCDLogicalLink &link, asam::mcd::MCDLogicalLinkState linkstate) override;
  virtual void onMonitoringFramesReady(asam::d::MCDMonitoringLink &monLink) override;
  virtual void onPrimitiveBufferOverflow(asam::d::MCDDiagComPrimitive &primitive, asam::mcd::MCDLogicalLink &link) override;
  virtual void onPrimitiveCanceledDuringExecution(asam::d::MCDDiagComPrimitive &primitive, asam::mcd::MCDLogicalLink &link) override;
  virtual void onPrimitiveCanceledFromQueue(asam::d::MCDDiagComPrimitive &primitive, asam::mcd::MCDLogicalLink &link) override;
  virtual void onPrimitiveError(asam::d::MCDDiagComPrimitive &primitive, asam::mcd::MCDLogicalLink &link, asam::mcd::MCDError &error) override;
  virtual void onPrimitiveHasIntermediateResult(asam::d::MCDDiagComPrimitive &primitive, asam::mcd::MCDLogicalLink &link, asam::d::MCDResultState &resultstate) override;
  virtual void onPrimitiveHasResult(asam::d::MCDDiagComPrimitive &primitive, asam::mcd::MCDLogicalLink &link, asam::d::MCDResultState &resultstate) override;
  virtual void onPrimitiveJobInfo(asam::d::MCDDiagComPrimitive &primitive, asam::mcd::MCDLogicalLink &link, asam::A_ASCIISTRING &info) override;
  virtual void onPrimitiveProgressInfo(asam::d::MCDDiagComPrimitive &primitive, asam::mcd::MCDLogicalLink &link, asam::A_UINT8 progress) override;
  virtual void onPrimitiveRepetitionStopped(asam::d::MCDDiagComPrimitive &primitive, asam::mcd::MCDLogicalLink &link) override;
  virtual void onPrimitiveTerminated(asam::d::MCDDiagComPrimitive &primitive, asam::mcd::MCDLogicalLink &link, asam::d::MCDResultState &resultstate) override;
  virtual void onPrimitiveIdle(asam::d::MCDDiagComPrimitive &primitive, asam::mcd::MCDLogicalLink &link, asam::d::MCDResultState &resultstate) override;
  virtual void onStaticInterfaceError(asam::mcd::MCDError &error) override;
  virtual void onSystemClampStateChanged(asam::A_ASCIISTRING &clamp, asam::d::MCDClampState clampState) override;
  virtual void onSystemConfigurationClosed() override;
  virtual void onSystemConfigurationOpened() override;
  virtual void onSystemError(asam::mcd::MCDError &error) override;
  virtual void onSystemLocked() override;
  virtual void onSystemLogicallyConnected() override;
  virtual void onSystemLogicallyDisconnected() override;
  virtual void onSystemProjectDeselected() override;
  virtual void onSystemProjectSelected() override;
  virtual void onSystemUnlocked() override ;
  virtual void onSystemVehicleInfoDeselected() override;
  virtual void onSystemVehicleInfoSelected() override;
};
} // namespace flash
} // namespace otx

#endif // __OTX_FLASH_BinFileDownloader_HPP__