/*
 * Copyright (C) 2016 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 agree 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 <stdio.h>
#include <stdlib.h>

#include <string>
#include <vector>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/strings.h>
#include <android-base/test_utils.h>
#include <bsdiff/bsdiff.h>
#include <gtest/gtest.h>
#include <openssl/sha.h>

#include "applypatch/applypatch_modes.h"
#include "common/test_constants.h"
#include "otautil/paths.h"
#include "otautil/print_sha1.h"
#include "otautil/sysutil.h"

using namespace std::string_literals;

// Loads a given partition and returns a string of form "EMMC:name:size:hash".
static std::string GetEmmcTargetString(const std::string& filename,
                                       const std::string& display_name = "") {
  std::string data;
  if (!android::base::ReadFileToString(filename, &data)) {
    PLOG(ERROR) << "Failed to read " << filename;
    return {};
  }

  uint8_t digest[SHA_DIGEST_LENGTH];
  SHA1(reinterpret_cast<const uint8_t*>(data.c_str()), data.size(), digest);

  return "EMMC:"s + (display_name.empty() ? filename : display_name) + ":" +
         std::to_string(data.size()) + ":" + print_sha1(digest);
}

class ApplyPatchModesTest : public ::testing::Test {
 protected:
  void SetUp() override {
    source = GetEmmcTargetString(from_testdata_base("boot.img"));
    ASSERT_FALSE(source.empty());

    std::string recovery_file = from_testdata_base("recovery.img");
    recovery = GetEmmcTargetString(recovery_file);
    ASSERT_FALSE(recovery.empty());

    ASSERT_TRUE(android::base::WriteStringToFile("", patched_file_.path));
    target = GetEmmcTargetString(recovery_file, patched_file_.path);
    ASSERT_FALSE(target.empty());

    Paths::Get().set_cache_temp_source(cache_source_.path);
  }

  std::string source;
  std::string target;
  std::string recovery;

 private:
  TemporaryFile cache_source_;
  TemporaryFile patched_file_;
};

static int InvokeApplyPatchModes(const std::vector<std::string>& args) {
  auto args_to_call = StringVectorToNullTerminatedArray(args);
  return applypatch_modes(args_to_call.size() - 1, args_to_call.data());
}

static void VerifyPatchedTarget(const std::string& target) {
  std::vector<std::string> pieces = android::base::Split(target, ":");
  ASSERT_EQ(4, pieces.size());
  ASSERT_EQ("EMMC", pieces[0]);

  std::string patched_emmc = GetEmmcTargetString(pieces[1]);
  ASSERT_FALSE(patched_emmc.empty());
  ASSERT_EQ(target, patched_emmc);
}

TEST_F(ApplyPatchModesTest, InvalidArgs) {
  // At least two args (including the filename).
  ASSERT_EQ(2, InvokeApplyPatchModes({ "applypatch" }));

  // Unrecognized args.
  ASSERT_EQ(2, InvokeApplyPatchModes({ "applypatch", "-x" }));
}

TEST_F(ApplyPatchModesTest, PatchModeEmmcTarget) {
  std::vector<std::string> args{
    "applypatch",
    "--bonus",
    from_testdata_base("bonus.file"),
    "--patch",
    from_testdata_base("recovery-from-boot.p"),
    "--target",
    target,
    "--source",
    source,
  };
  ASSERT_EQ(0, InvokeApplyPatchModes(args));
  VerifyPatchedTarget(target);
}

// Tests patching an eMMC target without a separate bonus file (i.e. recovery-from-boot patch has
// everything).
TEST_F(ApplyPatchModesTest, PatchModeEmmcTargetWithoutBonusFile) {
  std::vector<std::string> args{
    "applypatch", "--patch", from_testdata_base("recovery-from-boot-with-bonus.p"),
    "--target",   target,    "--source",
    source,
  };

  ASSERT_EQ(0, InvokeApplyPatchModes(args));
  VerifyPatchedTarget(target);
}

// Ensures that applypatch works with a bsdiff based recovery-from-boot.p.
TEST_F(ApplyPatchModesTest, PatchModeEmmcTargetWithBsdiffPatch) {
  // Generate the bsdiff patch of recovery-from-boot.p.
  std::string src_content;
  ASSERT_TRUE(android::base::ReadFileToString(from_testdata_base("boot.img"), &src_content));

  std::string tgt_content;
  ASSERT_TRUE(android::base::ReadFileToString(from_testdata_base("recovery.img"), &tgt_content));

  TemporaryFile patch_file;
  ASSERT_EQ(0,
            bsdiff::bsdiff(reinterpret_cast<const uint8_t*>(src_content.data()), src_content.size(),
                           reinterpret_cast<const uint8_t*>(tgt_content.data()), tgt_content.size(),
                           patch_file.path, nullptr));

  std::vector<std::string> args{
    "applypatch", "--patch", patch_file.path, "--target", target, "--source", source,
  };
  ASSERT_EQ(0, InvokeApplyPatchModes(args));
  VerifyPatchedTarget(target);
}

TEST_F(ApplyPatchModesTest, PatchModeInvalidArgs) {
  // Invalid bonus file.
  std::vector<std::string> args{
    "applypatch", "--bonus", "/doesntexist", "--patch", from_testdata_base("recovery-from-boot.p"),
    "--target",   target,    "--source",     source,
  };
  ASSERT_NE(0, InvokeApplyPatchModes(args));

  // With bonus file, but missing args.
  ASSERT_NE(0,
            InvokeApplyPatchModes({ "applypatch", "--bonus", from_testdata_base("bonus.file") }));
}

TEST_F(ApplyPatchModesTest, FlashMode) {
  std::vector<std::string> args{
    "applypatch", "--flash", from_testdata_base("recovery.img"), "--target", target,
  };
  ASSERT_EQ(0, InvokeApplyPatchModes(args));
  VerifyPatchedTarget(target);
}

TEST_F(ApplyPatchModesTest, FlashModeInvalidArgs) {
  std::vector<std::string> args{
    "applypatch", "--bonus", from_testdata_base("bonus.file"), "--flash", source,
    "--target",   target,
  };
  ASSERT_NE(0, InvokeApplyPatchModes(args));
}

TEST_F(ApplyPatchModesTest, CheckMode) {
  ASSERT_EQ(0, InvokeApplyPatchModes({ "applypatch", "--check", recovery }));
  ASSERT_EQ(0, InvokeApplyPatchModes({ "applypatch", "--check", source }));
}

TEST_F(ApplyPatchModesTest, CheckModeInvalidArgs) {
  ASSERT_EQ(2, InvokeApplyPatchModes({ "applypatch", "--check" }));
}

TEST_F(ApplyPatchModesTest, CheckModeNonEmmcTarget) {
  ASSERT_NE(0, InvokeApplyPatchModes({ "applypatch", "--check", from_testdata_base("boot.img") }));
}

TEST_F(ApplyPatchModesTest, ShowLicenses) {
  ASSERT_EQ(0, InvokeApplyPatchModes({ "applypatch", "--license" }));
}
