// Copyright 2016 The Bazel Authors. All rights reserved.
//
// 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.

#ifndef BAZEL_SRC_TOOLS_SINGLEJAR_ZLIB_INTERFACE_H_
#define BAZEL_SRC_TOOLS_SINGLEJAR_ZLIB_INTERFACE_H_

#include <cinttypes>
#include <cstdint>

#include "src/tools/singlejar/diag.h"
#include <zlib.h>

// An interface to zlib's inflater. Usage:
//   Inflater inflater;
//   inflater.DataToInflate(data, data_size);
//   for (;;) {
//     int rc = inflater.Inflate(out_buffer, out_buffer_size);
//       if (rc == Z_STREAM_END) {
//          break;
//       }
//       // If we ran out of out_buffer, create a new one
//   }
//   inflater.reset();
// NOTE that the sizes of the input/output buffers in zlib are 32-bit entities.
// Call Inflater::DataToInflate multiple times if 'data_size' in the usage
// example exceeds 4GB-1.
class Inflater {
 public:
  Inflater() {
    zstream_.zalloc = Z_NULL;
    zstream_.zfree = Z_NULL;
    zstream_.opaque = Z_NULL;
    zstream_.avail_in = 0;
    zstream_.next_in = nullptr;
    int ret = inflateInit2(&zstream_, -MAX_WBITS);
    if (ret != Z_OK) {
      diag_errx(2, "inflateInit2 returned %d\n", ret);
    }
  }

  ~Inflater() { inflateEnd(&zstream_); }

  void reset() { inflateReset(&zstream_); }

  void DataToInflate(const uint8_t* in_buffer, uint32_t in_buffer_length) {
    zstream_.next_in = const_cast<uint8_t*>(in_buffer);
    zstream_.avail_in = in_buffer_length;
  }

  int Inflate(uint8_t* out_buffer, uint32_t out_buffer_length) {
    zstream_.next_out = out_buffer;
    zstream_.avail_out = out_buffer_length;
    return inflate(&zstream_, Z_SYNC_FLUSH);
  }

  const uint8_t* next_in() const { return zstream_.next_in; }
  uint64_t total_in() const { return zstream_.total_in; }

  uint32_t available_out() const { return zstream_.avail_out; }
  uint64_t total_out() const { return zstream_.total_out; }

  const char* error_message() const { return zstream_.msg; }

 private:
  z_stream zstream_;
};

// A little wrapper around zlib's deflater.
// NOTE that the size of the data to inflate by a single call cannot exceed
// 4GB-1.
struct Deflater : z_stream {
  Deflater() {
    zalloc = Z_NULL;
    zfree = Z_NULL;
    opaque = Z_NULL;
    next_in = nullptr;
    avail_in = 0;
    next_out = nullptr;
    avail_out = 0;
    int ret = deflateInit2(this, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS,
                           8, Z_DEFAULT_STRATEGY);
    if (ret != Z_OK) {
      diag_errx(2, "deflateInit returned %d (%s)", ret, msg);
    }
  }

  ~Deflater() { deflateEnd(this); }

  int Deflate(const uint8_t* data, uint32_t data_size, int flag) {
    next_in = const_cast<uint8_t*>(data);
    avail_in = data_size;
    return deflate(this, flag);
  }
};

#endif  // BAZEL_SRC_TOOLS_SINGLEJAR_ZLIB_INTERFACE_H_
