// 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 SRC_TOOLS_SINGLEJAR_COMBINERS_H_
#define SRC_TOOLS_SINGLEJAR_COMBINERS_H_ 1

#include <memory>
#include <string>

#include "src/tools/singlejar/transient_bytes.h"
#include "src/tools/singlejar/zip_headers.h"

// An interface for combining the files.
class Combiner {
 public:
  virtual ~Combiner();
  // Merges the contents of the given Zip entry to this instance.
  virtual bool Merge(const CDH *cdh, const LH *lh) = 0;
  // Returns a point to the buffer containing Local Header followed by the
  // payload. The caller is responsible of freeing the buffer. If `compress'
  // is not set, the payload is a copy of the bytes held by this combiner.
  // Otherwise the payload is compressed, provided that the compressed data
  // is smaller than the original.
  virtual void *OutputEntry(bool compress) = 0;
};

// An output jar entry consisting of a concatenation of the input jar
// entries. Byte sequences can be appended to it, too.
class Concatenator : public Combiner {
 public:
  Concatenator(const std::string &filename, bool insert_newlines = true)
      : filename_(filename), insert_newlines_(insert_newlines) {}

  ~Concatenator() override;

  bool Merge(const CDH *cdh, const LH *lh) override;

  void *OutputEntry(bool compress) override;

  void Append(const char *s, size_t n) {
    CreateBuffer();
    buffer_->Append(reinterpret_cast<const uint8_t *>(s), n);
  }

  void Append(const char *s) { Append(s, strlen(s)); }

  void Append(const std::string &str) { Append(str.c_str(), str.size()); }

  const std::string &filename() const { return filename_; }

 private:
  void CreateBuffer() {
    if (!buffer_.get()) {
      buffer_.reset(new TransientBytes());
    }
  }
  const std::string filename_;
  std::unique_ptr<TransientBytes> buffer_;
  std::unique_ptr<Inflater> inflater_;
  bool insert_newlines_;
};

// The combiner that does nothing. Useful to represent for instance directory
// entries: once a directory entry has been created and added to the output
// jar, the subsequent entries are ignored on input, and nothing is output.
class NullCombiner : public Combiner {
 public:
  ~NullCombiner() override;
  bool Merge(const CDH *cdh, const LH *lh) override;
  void *OutputEntry(bool compress) override;
};

// Combines the contents of the multiple input entries which are XML
// files into a single XML output entry with given top level XML tag.
class XmlCombiner : public Combiner {
 public:
  XmlCombiner(const std::string &filename, const char *xml_tag)
      : filename_(filename), xml_tag_(xml_tag) {}
  ~XmlCombiner() override;

  bool Merge(const CDH *cdh, const LH *lh) override;

  void *OutputEntry(bool compress) override;

  const std::string filename() const { return filename_; }

 private:
  const std::string filename_;
  const char *xml_tag_;
  std::unique_ptr<Concatenator> concatenator_;
  std::unique_ptr<Inflater> inflater_;
};

// A wrapper around Concatenator allowing to append
//   NAME=VALUE
// lines to the contents.
// NOTE that it does not allow merging existing entries.
class PropertyCombiner : public Concatenator {
 public:
  PropertyCombiner(const std::string &filename) : Concatenator(filename) {}
  ~PropertyCombiner();

  bool Merge(const CDH *cdh, const LH *lh) override;

  void AddProperty(const char *key, const char *value) {
    // TODO(asmundak): deduplicate properties.
    Append(key);
    Append("=", 1);
    Append(value);
    Append("\n", 1);
  }

  void AddProperty(const std::string &key, const std::string &value) {
    // TODO(asmundak): deduplicate properties.
    Append(key);
    Append("=", 1);
    Append(value);
    Append("\n", 1);
  }
};

#endif  //  SRC_TOOLS_SINGLEJAR_COMBINERS_H_
