// 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 <map>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>

#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 std::string &xml_tag)
      : filename_(filename),
        start_tag_("<" + xml_tag + ">"),
        end_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 std::string start_tag_;
  const std::string end_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_
