/**
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.
 */
/**
 * @file GzipDeflateTransformation.cc
 */

#include <cstring>
#include <vector>
#include <zlib.h>
#include <cinttypes>
#include <string_view>
#include "tscpp/api/TransformationPlugin.h"
#include "tscpp/api/GzipDeflateTransformation.h"
#include "logging_internal.h"

using namespace atscppapi::transformations;
using std::vector;

namespace
{
const int          GZIP_MEM_LEVEL = 8;
const int          WINDOW_BITS    = 31; // Always use 31 for gzip.
const unsigned int ONE_KB         = 1024;
} // namespace

/**
 * @private
 */
struct atscppapi::transformations::GzipDeflateTransformationState : noncopyable {
  z_stream                   z_stream_;
  bool                       z_stream_initialized_;
  TransformationPlugin::Type transformation_type_;
  int64_t                    bytes_produced_;

  GzipDeflateTransformationState(TransformationPlugin::Type type)
    : z_stream_initialized_(false), transformation_type_(type), bytes_produced_(0)
  {
    memset(&z_stream_, 0, sizeof(z_stream_));
    int err = deflateInit2(&z_stream_, Z_DEFAULT_COMPRESSION, Z_DEFLATED, WINDOW_BITS, GZIP_MEM_LEVEL, Z_DEFAULT_STRATEGY);

    if (Z_OK != err) {
      LOG_ERROR("deflateInit2 failed with error code '%d'.", err);
    } else {
      z_stream_initialized_ = true;
    }
  };

  ~GzipDeflateTransformationState()
  {
    if (z_stream_initialized_) {
      deflateEnd(&z_stream_);
    }
  };
};

GzipDeflateTransformation::GzipDeflateTransformation(Transaction &transaction, TransformationPlugin::Type type)
  : TransformationPlugin(transaction, type)
{
  state_ = std::make_unique<GzipDeflateTransformationState>(type);
}

GzipDeflateTransformation::~GzipDeflateTransformation() {}

void
GzipDeflateTransformation::consume(std::string_view data)
{
  if (data.size() == 0) {
    return;
  }

  if (!state_->z_stream_initialized_) {
    LOG_ERROR("Unable to deflate output because the z_stream was not initialized.");
    return;
  }

  int iteration               = 0;
  state_->z_stream_.data_type = Z_ASCII;
  state_->z_stream_.next_in   = reinterpret_cast<unsigned char *>(const_cast<char *>(data.data()));
  state_->z_stream_.avail_in  = data.length();

  // For small payloads the size can actually be greater than the original input
  // so we'll use twice the original size to avoid needless repeated calls to deflate.
  unsigned long         buffer_size = (data.length() < ONE_KB) ? 2 * ONE_KB : data.length();
  vector<unsigned char> buffer(buffer_size);

  do {
    LOG_DEBUG("Iteration %d: Deflate will compress %ld bytes", ++iteration, data.size());
    state_->z_stream_.avail_out = buffer_size;
    // next_out needs to be set to nullptr before we return since it points to a local buffer
    // coverity[WRAPPER_ESCAPE: FALSE]
    state_->z_stream_.next_out = &buffer[0];

    int err = deflate(&state_->z_stream_, Z_SYNC_FLUSH);
    if (Z_OK != err) {
      LOG_ERROR("Iteration %d: Deflate failed to compress %ld bytes with error code '%d'", iteration, data.size(), err);
      state_->z_stream_.next_out = nullptr;
      return;
    }

    int bytes_to_write       = buffer_size - state_->z_stream_.avail_out;
    state_->bytes_produced_ += bytes_to_write;

    LOG_DEBUG("Iteration %d: Deflate compressed %ld bytes to %d bytes, producing output...", iteration, data.size(),
              bytes_to_write);
    produce(std::string_view(reinterpret_cast<char *>(&buffer[0]), static_cast<size_t>(bytes_to_write)));
  } while (state_->z_stream_.avail_out == 0);

  state_->z_stream_.next_out = nullptr;

  if (state_->z_stream_.avail_in != 0) {
    LOG_ERROR("Inflate finished with data still remaining in the buffer of size '%u'", state_->z_stream_.avail_in);
  }
}

void
GzipDeflateTransformation::handleInputComplete()
{
  // We will flush out anything that's remaining in the gzip buffer
  int           status      = Z_OK;
  int           iteration   = 0;
  const int     buffer_size = 1024; // 1024 bytes is usually more than enough for the epilogue
  unsigned char buffer[buffer_size];

  /* Deflate remaining data */
  do {
    LOG_DEBUG("Iteration %d: Gzip deflate finalizing.", ++iteration);
    state_->z_stream_.data_type = Z_ASCII;
    state_->z_stream_.avail_out = buffer_size;
    state_->z_stream_.next_out  = buffer;

    status = deflate(&state_->z_stream_, Z_FINISH);

    int bytes_to_write       = buffer_size - state_->z_stream_.avail_out;
    state_->bytes_produced_ += bytes_to_write;

    if (status == Z_OK || status == Z_STREAM_END) {
      LOG_DEBUG("Iteration %d: Gzip deflate finalize had an extra %d bytes to process, status '%d'. Producing output...", iteration,
                bytes_to_write, status);
      produce(std::string_view(reinterpret_cast<char *>(buffer), static_cast<size_t>(bytes_to_write)));
    } else if (status != Z_STREAM_END) {
      LOG_ERROR("Iteration %d: Gzip deflate finalize produced an error '%d'", iteration, status);
    }
  } while (status == Z_OK);

  int64_t bytes_written = setOutputComplete();
  if (state_->bytes_produced_ != bytes_written) {
    LOG_ERROR("Gzip bytes produced sanity check failed, deflated bytes = %" PRId64 " != written bytes = %" PRId64,
              state_->bytes_produced_, bytes_written);
  }
}
