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

#include <brillo/secure_blob.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 google::protobuf::RepeatedPtrField;
using std::string;

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(const RepeatedPtrField<Extent>& extents,
            uint32_t block_size) override {
    return true;
  }
  bool Write(const void* bytes, size_t count) override {
    data_->insert(data_->end(),
                  static_cast<const uint8_t*>(bytes),
                  static_cast<const uint8_t*>(bytes) + count);
    return true;
  }

 private:
  brillo::Blob* data_;
};

template <typename W>
bool DecompressWithWriter(const brillo::Blob& in, brillo::Blob* out) {
  out->reserve(in.size());
  std::unique_ptr<ExtentWriter> writer(
      new W(std::make_unique<MemoryExtentWriter>(out)));
  // Init() parameters are ignored by the testing MemoryExtentWriter.
  bool ok = writer->Init({}, 1);
  ok = writer->Write(in.data(), in.size()) && 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);
  }
};

typedef ::testing::Types<BzipTest, XzTest> ZipTestTypes;

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_EQ(0, 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());
}

TYPED_TEST(ZipTest, CompressELFTest) {
  string path = test_utils::GetBuildArtifactsPath("delta_generator");
  brillo::Blob in;
  ASSERT_TRUE(utils::ReadFile(path, &in));
  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_EQ(0, memcmp(in.data(), decompressed.data(), in.size()));
}

}  // namespace chromeos_update_engine
