/*===========================================================================
  Copyright (c) 2019 QUALCOMM Technologies Incorporated.
  All Rights Reserved.
  Qualcomm Confidential and Proprietary
=============================================================================*/

#include <stddef.h>
#include <stdint.h>
#include "IMinidumpService_invoke.h"
#include "qsee_env.h"
#include "stringl.h"
#include "lz4.h"
#include "IMemSpace.h"
#include "object.h"

/* Global variables to store destination buffer for compression*/
uint64_t dest_addr,dest_size = 0;

int32_t CMinidumpService_CompressMinidumpRegion(void *me,
                     Object compress_region, Object destination_region,
                     uint64_t* compressed_length_out )
{
  int ret = Object_ERROR;
  Object compress_space= Object_NULL;
  Object compress_memMap = Object_NULL, dest_memMap = Object_NULL;
  uint32_t perm = IMemRegion_PERM_RW;
  uint64_t compress_in_addr = 0, compress_in_size = 0;
  int l4z_len_to_compress = 0;

  /* get space*/
  compress_space = qsee_get_space();
  if (Object_isNull(compress_space)) 
  {
    goto bail;
  }
  
  /* Map destination buffer for Compression */
  ret = IMemSpace_map(compress_space, destination_region, perm, &dest_addr, &dest_size, &dest_memMap);
  if (Object_isERROR(ret)) 
  {
    dest_memMap = Object_NULL;
    ret = Object_ERROR;
    goto bail;
  }

  ret = IMemSpace_map(compress_space, compress_region, perm, &compress_in_addr, &compress_in_size, &compress_memMap);
  if (Object_isERROR(ret)) 
  {
    compress_memMap = Object_NULL;
    ret = Object_ERROR;
    goto bail;
  }

  /* Compress using LZ4 algorithm */
  l4z_len_to_compress = LZ4_compress((char*)(compress_in_addr), (char*)(dest_addr), (int)(compress_in_size));
  
  /* Copy the compression output from destination buffer to source buffer*/
  memscpy((void*)(compress_in_addr),l4z_len_to_compress,(char*)(dest_addr),l4z_len_to_compress);
  
  /* Update the compressed output length */
  *compressed_length_out = l4z_len_to_compress;

  ret = Object_OK;
  
bail:
  Object_ASSIGN_NULL(compress_memMap);
  Object_ASSIGN_NULL(compress_space);
  Object_ASSIGN_NULL(dest_memMap);

  return ret;
}


// This implementation does not require a context record, so `retain` and
// `release` are no-ops.

#define CMinidumpService_release(ctx)   Object_OK
#define CMinidumpService_retain(ctx)    Object_OK

static IMinidumpService_DEFINE_INVOKE(CMinidumpService_invoke, CMinidumpService_, void*)

int32_t CMinidumpCompress_open(Object cred, Object *objOut)
{
   *objOut = (Object) { CMinidumpService_invoke, NULL };
   return Object_OK;
}
