// clang-format off
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/diag/prdf/common/framework/register/iipCaptureData.h $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2012,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

#ifndef iipCaptureData_h
#define iipCaptureData_h

// Class Specification *************************************************
//
// Class name:   CaptureData
// Parent class: None.
//
// Summary: This class provides a queue-like buffer for recording Scan
//          Comm Register data.
//
//          When this class is constructed or the Clear() member
//          function is called, the buffer is empty.  The Add()
//          function adds data to the front or back of this buffer.
//          The data is ordered according to the sequence of Add()
//          calls and the Place parameter (FRONT or BACK).  A Scan
//          Comm Register is passed to the Add() function and the
//          register is read during the Add() function.  The data is
//          then stored internally.  Whenever the Copy() member
//          function is called, the current internal data is copied to
//          the specified buffer with respect to the current ordering.
//          Only the number of bytes specified are copied.  Therefore,
//          any data that MUST be copied should be added using the
//          FRONT placement.
//
// Cardinality: N
//
// Performance/Implementation:
//   Space Complexity: Linear based on the number of Add() calls
//   Time Complexity:  All member functions constant unless otherwise
//                     stated.
//
// Usage Examples:
//
// BIT8 data[BUFFER_SIZE];
//
// void foo(TARGETING::TargetHandle_t chipId, ScanCommRegisterAccess & scr)
//   {
//   CaptureData captureData;
//
//   captureData.Add(chipId, scr, CaptureData::FRONT);
//   captureData.Add(chipId, scr, CaptureData::BACK);
//
//   int bytesCopied = captureData.Copy(data, BUFFER_SIZE);
//   }
//
// End Class Specification *********************************************

/*--------------------------------------------------------------------*/
/* Reference the virtual function tables and inline function
   defintions in another translation unit.                            */
/*--------------------------------------------------------------------*/

#include <list>

#include <hei_includes.hpp>

#include <prdfPlatServices.H>
#include <functional>  // @jl04 a Needed for the unary function in new predicate.

#ifdef __HOSTBOOT_MODULE

  // FIXME: RTC 73204 was opened to add support for these in hostboot. They will
  //        need to be removed once the issue has been resolved.
  #ifndef htonl
    #define htonl(foo) (foo)
  #endif

  #ifndef htons
    #define htons(foo) (foo)
  #endif

  #ifndef ntohl
    #define ntohl(foo) (foo)
  #endif

  #ifndef ntohs
    #define ntohs(foo) (foo)
  #endif

#else

  #include <netinet/in.h>

#endif

namespace libhei
{

// Forward Declarations
class Register;
class ScanCommRegisterAccess;
class BitString;

// @jl04 a start
// @jl04 a Added this enumeration for error log compression, elimination of secondary regs.
  enum RegType
  {
    PRIMARY   = 1,
    SECONDARY = 2
  };
// @jl04 a Stop

/**
 Capture data class
 @author Doug Gilbert
 @version V5R2
*/
class CaptureData
{
public:

  enum Place
  {
    FRONT,
    BACK
  };

  enum
  {
    INITIAL_DATA_COUNT = 80,
    ENTRY_FIXED_SIZE = 8,
    MAX_ENTRY_SIZE = 128
  };

  /**
   Constructor
   */
  CaptureData(void);

  /*
   Copy constructor - default is ok
   */
//  CaptureData(const CaptureData & c);

  /*
   Assignment operator - default is ok
   */
//  CaptureData & operator=(const CaptureData & c);

  /**
   Destructor
   */
// dg05d  ~CaptureData(void);   // compiler default is ok

  /**
   Clear out capture data
   <ul>
   <br><b>Parameters:None
   <br><b>Returns:Nothing
   <br><b>Requirments:None.
   <br><b>Promises: All capture data cleared ( copy(...) == 0 )
   </ul><br>
   */
  void Clear(void);

  // dg00 start
  /**
   Add scr & data to capture log
   <ul>
   <br><b>Parameter:  chipHandle     target handle of chip object
   <br><b>Parameter:  scan comm id (unique one btye code representing scan comm address)
   <br><b>Parameter:  Scan comm register object
   <br><b>Parameter:  Optional location in capure vector [FRONT | BACK] def = BACK
   <br><b>Returns:   Nothing
   <br><b>Requires:  Nothing
   <br><b>Promises:  scr.Read()
   <br><b>Notes:     This is the required Add() method for Regatta and beyond
   </ul><br>
   */
  void Add( TARGETING::TargetHandle_t i_pchipHandle, int scomId,
            Register & scr, Place place = BACK,
            RegType type = PRIMARY);  // @jl04 c. Changed this to add the type to the end of the parms.
  // dg00 end

  /*  REMOVE for FSP
   Add scr & data to capture log
   <ul>
   <br><b>Parameter:  chipHandle     target handle of chip object
   <br><b>Parameter:  Scan comm register object
   <br><b>Parameter:  Optional location in capure vector [FRONT | BACK] def = BACK
   <br><b>Returns:   Nothing
   <br><b>Requires:  Nothing
   <br><b>Promises:  scr.Read()
   <br><b>Notes:     This is the required Add() method for pre-Regatta
   </ul><br>

  void Add(TARGETING::TargetHandle_t chipId, Register & scr,
      Place place = BACK);
*/

  // dg02 start
  /**
   Add scr & data to capture log
   <ul>
   <br><b>Parameter:  i_pchipHandle Handle of chip object
   <br><b>Parameter:  scan comm id (unique one btye code representing scan comm address)
   <br><b>Parameter:  BitString
   <br><b>Parameter:  Optional location in capure vector [FRONT | BACK] def = BACK
   <br><b>Returns:   Nothing
   <br><b>Requires:  Nothing
   <br><b>Promises:
   <br><b>Notes:     This is available for Regatta and beyond. Not implemented on Condor
   </ul><br>
   */
  void Add( TARGETING::TargetHandle_t i_pchipHandle, int scomId,
            const BitString & bs, Place place = BACK);

  // dg02 end

// start @jl04a
  /**
   Drop scr & data from capture log
   <ul>
   <br><b>Parameter:  Type of capture vector [PRIMARY | SECONDARY] def = PRIMARY. SECONDARIES dropped on connected.
   <br><b>Returns:   Nothing
   <br><b>Requires:  Nothing
   <br><b>Promises:
   </ul><br>
   */
void Drop(RegType type);  //@jl04a
// end @jl04a

    /**
     * @brief  Copies the capture data to a buffer.
     *
     * The capture data is copied to the buffer in the order it exists in the
     * vector until all entries have been added or until the buffer is full.
     *
     * @param  i_buffer     Pointer to buffer.
     * @param  i_bufferSize Maximum size of the buffer.
     * @return The actual size of the data buffer. The value will always be less
     *         than or equal to the maximum buffer size.
     */
    uint32_t Copy( uint8_t * i_buffer, uint32_t i_bufferSize ) const;

  // dg08a -->
  /**
   Reconstruct data from flat data
   <ul>
   <br><b>Parameter:  i_flatdata ptr to flat data
   <br><b>Returns:   reference to the new capture data
   <br><b>Requirements: None
   <br><b>Promises:  CaptureData created form flatdata
   <br><b>Note:  i_flatdata -> (uin32_t)size + data created by Copy()
                 data is network ordered bytes.
   <ul><br>
   */
  CaptureData & operator=(const uint8_t *i_flatdata);
  // <-- dg08a

private:

  // Notes *************************************************************
  //
  // Instead of maintaining an actual data buffer, an auxiliary data
  // structure is used to maintain data in a specific order.  The main
  // reason for this is that since data can be entered in the front or
  // back of the buffer, the data must be copied to maintain the order.
  // It is more efficient to copy a number of pointers than a large
  // data buffer.  However, there is added complexity since the data
  // structure contains a pointer to dynamic data that must be
  // allocated/deallocated properly.
  //
  // A vector of data structures is maintained that is given an initial
  // size.  The vector can grow dynamically, but this can be expensive
  // in terms of copying and memory fragmentation.  To prevent this, the
  // number of calls to Add() between calls to Clear() should not exceed
  // the enum INITIAL_DATA_COUNT.
  //
  // End Notes *********************************************************

  class Data
  {
  public:
    // Ctor
    Data(TARGETING::TargetHandle_t i_pchipHandle= nullptr,   // dg01
         uint16_t a = 0,
         uint16_t  dbl = 0,
         uint8_t * dPtr = nullptr)
    :
    chipHandle(i_pchipHandle),
    address(a),
    dataByteLength(dbl),
    dataPtr(dPtr)
    {}

    ~Data(void)                     // dg05a
    {                               // dg05a
      if(dataPtr != nullptr)           // dg05a
      {                             // dg05a
        delete [] dataPtr;          // pw01
      }                             // dg05a
    }                               // dg05a
    // Data
    TARGETING::TargetHandle_t  chipHandle;
    uint16_t address;
    uint16_t  dataByteLength;
    uint8_t * dataPtr;

    RegType registerType;          // @jl04a

    Data(const Data & d);
    Data & operator=(const Data & d);
  };

// We should probably use a link list instead of a vector
  typedef std::list<Data> DataContainerType;
  typedef DataContainerType::iterator DataIterator;
  typedef DataContainerType::const_iterator ConstDataIterator;

  DataContainerType             data;

    /** Private function to facilitate the adding of caputre data to the
     *  internal vector */
    void AddDataElement( TARGETING::TargetHandle_t i_trgt, int i_scomId,
                         const BitString * i_bs, Place i_place,
                         RegType i_type = PRIMARY );

  // Predicate for deciding to delete an element of data from a Capture Data list.
  class prdfCompareCaptureDataType : public std::unary_function<Data &, bool>
  {
    public:
      prdfCompareCaptureDataType(RegType i_ctor_input) : __private_storage(i_ctor_input){};
      bool operator() (Data &i)
      {
        return (i.registerType == __private_storage);
      };


    private:
    //Private storage for value passed in.
      RegType __private_storage;
    //Constructor allows a value to be passed in to compare against.
  };

  // Predicate for deciding whether to delete an
  // element of data from a Capture Data list.
  class prdfCompareCaptureDataEntry :
      public std::unary_function<Data &, bool>
  {
    public:
      prdfCompareCaptureDataEntry(
                    TARGETING::TargetHandle_t chipHandle,
                    uint16_t address) :
                    __chipHandle(chipHandle),
                    __address(address) {};
      bool operator() (Data &i)
      {
        return ((i.chipHandle == __chipHandle) &&
                (i.address    == __address));
      };

    private:
      TARGETING::TargetHandle_t  __chipHandle;
      uint16_t __address;
  };

public:

  /**
   * @brief   Merge scom register data from two captures
   * @param   i_cd  secondary capture data to merge
   */
  void mergeData(CaptureData & i_cd);

  /**
   * @brief   Get the Scom data pointer
   * @return  the Scom data pointer
   */
  DataContainerType * getData() { return &data; }



};

} // end namespace libhei

#endif
// clang-format on
