//
// Copyright (C) 2011 The Android Open Source Project
//
// 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.
//

#include <string.h>
#include <unistd.h>

#include <string>
#include <vector>

#include <brillo/make_unique_ptr.h>
#include <gtest/gtest.h>

#include "update_engine/common/test_utils.h"
#include "update_engine/payload_consumer/bzip_extent_writer.h"
#include "update_engine/payload_consumer/extent_writer.h"
#include "update_engine/payload_consumer/xz_extent_writer.h"
#include "update_engine/payload_generator/bzip.h"
#include "update_engine/payload_generator/xz.h"

using chromeos_update_engine::test_utils::kRandomString;
using std::string;
using std::vector;

namespace chromeos_update_engine {

namespace {

// ExtentWriter class that writes to memory, used to test the decompression
// step with the corresponding extent writer.
class MemoryExtentWriter : public ExtentWriter {
 public:
  // Creates the ExtentWriter that will write all the bytes to the passed |data|
  // blob.
  explicit MemoryExtentWriter(brillo::Blob* data) : data_(data) {
    data_->clear();
  }
  ~MemoryExtentWriter() override = default;

  bool Init(FileDescriptorPtr fd,
            const vector<Extent>& extents,
            uint32_t block_size) override {
    return true;
  }
  bool Write(const void* bytes, size_t count) override {
    data_->reserve(data_->size() + count);
    data_->insert(data_->end(),
                  static_cast<const uint8_t*>(bytes),
                  static_cast<const uint8_t*>(bytes) + count);
    return true;
  }
  bool EndImpl() override { return true; }

 private:
  brillo::Blob* data_;
};

template <typename W>
bool DecompressWithWriter(const brillo::Blob& in, brillo::Blob* out) {
  std::unique_ptr<ExtentWriter> writer(
      new W(brillo::make_unique_ptr(new MemoryExtentWriter(out))));
  // Init() parameters are ignored by the testing MemoryExtentWriter.
  bool ok = writer->Init(nullptr, {}, 1);
  ok = writer->Write(in.data(), in.size()) && ok;
  // Call End() even if the Write failed.
  ok = writer->End() && ok;
  return ok;
}

}  // namespace

template <typename T>
class ZipTest : public ::testing::Test {
 public:
  bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const = 0;
  bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const = 0;
};

class BzipTest {};

template <>
class ZipTest<BzipTest> : public ::testing::Test {
 public:
  bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const {
    return BzipCompress(in, out);
  }
  bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const {
    return DecompressWithWriter<BzipExtentWriter>(in, out);
  }
};

class XzTest {};

template <>
class ZipTest<XzTest> : public ::testing::Test {
 public:
  bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const {
    return XzCompress(in, out);
  }
  bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const {
    return DecompressWithWriter<XzExtentWriter>(in, out);
  }
};

#ifdef __ANDROID__
typedef ::testing::Types<BzipTest, XzTest> ZipTestTypes;
#else
// Chrome OS implementation of Xz compressor just returns false.
typedef ::testing::Types<BzipTest> ZipTestTypes;
#endif  // __ANDROID__

TYPED_TEST_CASE(ZipTest, ZipTestTypes);

TYPED_TEST(ZipTest, SimpleTest) {
  string in_str(
      "this should compress well xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
  brillo::Blob in(in_str.begin(), in_str.end());
  brillo::Blob out;
  EXPECT_TRUE(this->ZipCompress(in, &out));
  EXPECT_LT(out.size(), in.size());
  EXPECT_GT(out.size(), 0U);
  brillo::Blob decompressed;
  EXPECT_TRUE(this->ZipDecompress(out, &decompressed));
  EXPECT_EQ(in.size(), decompressed.size());
  EXPECT_TRUE(!memcmp(in.data(), decompressed.data(), in.size()));
}

TYPED_TEST(ZipTest, PoorCompressionTest) {
  brillo::Blob in(std::begin(kRandomString), std::end(kRandomString));
  brillo::Blob out;
  EXPECT_TRUE(this->ZipCompress(in, &out));
  EXPECT_GT(out.size(), in.size());
  brillo::Blob decompressed;
  EXPECT_TRUE(this->ZipDecompress(out, &decompressed));
  EXPECT_EQ(in.size(), decompressed.size());
  EXPECT_EQ(in, decompressed);
}

TYPED_TEST(ZipTest, MalformedZipTest) {
  brillo::Blob in(std::begin(kRandomString), std::end(kRandomString));
  brillo::Blob out;
  EXPECT_FALSE(this->ZipDecompress(in, &out));
}

TYPED_TEST(ZipTest, EmptyInputsTest) {
  brillo::Blob in;
  brillo::Blob out;
  EXPECT_TRUE(this->ZipDecompress(in, &out));
  EXPECT_EQ(0U, out.size());

  EXPECT_TRUE(this->ZipCompress(in, &out));
  EXPECT_EQ(0U, out.size());
}

}  // namespace chromeos_update_engine
