/*
 * Copyright (C) 2018 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.
 */

/*
 * The tests in this file operate on a higher level than the tests in the other
 * files. Here, all tests execute the idmap2 binary and only depend on
 * libidmap2 to verify the output of idmap2.
 */
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <cerrno>
#include <cstdlib>
#include <cstring>  // strerror
#include <fstream>
#include <memory>
#include <sstream>
#include <string>
#include <vector>

#include "R.h"
#include "TestHelpers.h"
#include "androidfw/PosixUtils.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "idmap2/FileUtils.h"
#include "idmap2/Idmap.h"
#include "private/android_filesystem_config.h"

using ::android::util::ExecuteBinary;
using ::testing::NotNull;

namespace android::idmap2 {

class Idmap2BinaryTests : public Idmap2Tests {};

namespace {

void AssertIdmap(const Idmap& idmap, const std::string& target_apk_path,
                 const std::string& overlay_apk_path) {
  // check that the idmap file looks reasonable (IdmapTests is responsible for
  // more in-depth verification)
  ASSERT_EQ(idmap.GetHeader()->GetMagic(), kIdmapMagic);
  ASSERT_EQ(idmap.GetHeader()->GetVersion(), kIdmapCurrentVersion);
  ASSERT_EQ(idmap.GetHeader()->GetTargetPath(), target_apk_path);
  ASSERT_EQ(idmap.GetHeader()->GetOverlayPath(), overlay_apk_path);
  ASSERT_EQ(idmap.GetData().size(), 1U);
}

#define ASSERT_IDMAP(idmap_ref, target_apk_path, overlay_apk_path)                      \
  do {                                                                                  \
    ASSERT_NO_FATAL_FAILURE(AssertIdmap(idmap_ref, target_apk_path, overlay_apk_path)); \
  } while (0)

#ifdef __ANDROID__
#define SKIP_TEST_IF_CANT_EXEC_IDMAP2           \
  do {                                          \
    const uid_t uid = getuid();                 \
    if (uid != AID_ROOT && uid != AID_SYSTEM) { \
      GTEST_SKIP();                             \
    }                                           \
  } while (0)
#else
#define SKIP_TEST_IF_CANT_EXEC_IDMAP2
#endif

}  // namespace

TEST_F(Idmap2BinaryTests, Create) {
  SKIP_TEST_IF_CANT_EXEC_IDMAP2;

  // clang-format off
  auto result = ExecuteBinary({"idmap2",
                               "create",
                               "--target-apk-path", GetTargetApkPath(),
                               "--overlay-apk-path", GetOverlayApkPath(),
                               "--idmap-path", GetIdmapPath()});
  // clang-format on
  ASSERT_THAT(result, NotNull());
  ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;

  struct stat st;
  ASSERT_EQ(stat(GetIdmapPath().c_str(), &st), 0);

  std::ifstream fin(GetIdmapPath());
  const auto idmap = Idmap::FromBinaryStream(fin);
  fin.close();

  ASSERT_TRUE(idmap);
  ASSERT_IDMAP(**idmap, GetTargetApkPath(), GetOverlayApkPath());

  unlink(GetIdmapPath().c_str());
}

TEST_F(Idmap2BinaryTests, Dump) {
  SKIP_TEST_IF_CANT_EXEC_IDMAP2;

  // clang-format off
  auto result = ExecuteBinary({"idmap2",
                               "create",
                               "--target-apk-path", GetTargetApkPath(),
                               "--overlay-apk-path", GetOverlayApkPath(),
                               "--idmap-path", GetIdmapPath()});
  // clang-format on
  ASSERT_THAT(result, NotNull());
  ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;

  // clang-format off
  result = ExecuteBinary({"idmap2",
                          "dump",
                          "--idmap-path", GetIdmapPath()});
  // clang-format on
  ASSERT_THAT(result, NotNull());
  ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
  ASSERT_NE(result->stdout.find(R::target::integer::literal::int1 + " -> 0x7f010000 integer/int1"),
            std::string::npos);
  ASSERT_NE(result->stdout.find(R::target::string::literal::str1 + " -> 0x7f020000 string/str1"),
            std::string::npos);
  ASSERT_NE(result->stdout.find(R::target::string::literal::str3 + " -> 0x7f020001 string/str3"),
            std::string::npos);
  ASSERT_NE(result->stdout.find(R::target::string::literal::str4 + " -> 0x7f020002 string/str4"),
            std::string::npos);

  // clang-format off
  result = ExecuteBinary({"idmap2",
                          "dump",
                          "--verbose",
                          "--idmap-path", GetIdmapPath()});
  // clang-format on
  ASSERT_THAT(result, NotNull());
  ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
  ASSERT_NE(result->stdout.find("00000000: 504d4449  magic"), std::string::npos);

  // clang-format off
  result = ExecuteBinary({"idmap2",
                          "dump",
                          "--verbose",
                          "--idmap-path", GetTestDataPath() + "/DOES-NOT-EXIST"});
  // clang-format on
  ASSERT_THAT(result, NotNull());
  ASSERT_NE(result->status, EXIT_SUCCESS);

  unlink(GetIdmapPath().c_str());
}

TEST_F(Idmap2BinaryTests, Scan) {
  SKIP_TEST_IF_CANT_EXEC_IDMAP2;

  const std::string overlay_static_no_name_apk_path =
      GetTestDataPath() + "/overlay/overlay-no-name-static.apk";
  const std::string overlay_static_1_apk_path = GetTestDataPath() + "/overlay/overlay-static-1.apk";
  const std::string overlay_static_2_apk_path = GetTestDataPath() + "/overlay/overlay-static-2.apk";
  const std::string idmap_static_no_name_path =
      Idmap::CanonicalIdmapPathFor(GetTempDirPath(), overlay_static_no_name_apk_path);
  const std::string idmap_static_1_path =
      Idmap::CanonicalIdmapPathFor(GetTempDirPath(), overlay_static_1_apk_path);
  const std::string idmap_static_2_path =
      Idmap::CanonicalIdmapPathFor(GetTempDirPath(), overlay_static_2_apk_path);

  // single input directory, recursive
  // clang-format off
  auto result = ExecuteBinary({"idmap2",
                               "scan",
                               "--input-directory", GetTestDataPath(),
                               "--recursive",
                               "--target-package-name", "test.target",
                               "--target-apk-path", GetTargetApkPath(),
                               "--output-directory", GetTempDirPath(),
                               "--override-policy", "public"});
  // clang-format on
  ASSERT_THAT(result, NotNull());
  ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
  std::stringstream expected;
  expected << idmap_static_no_name_path << std::endl;
  expected << idmap_static_1_path << std::endl;
  expected << idmap_static_2_path << std::endl;
  ASSERT_EQ(result->stdout, expected.str());

  auto idmap_static_no_name_raw_string = utils::ReadFile(idmap_static_no_name_path);
  auto idmap_static_no_name_raw_stream = std::istringstream(*idmap_static_no_name_raw_string);
  auto idmap_static_no_name = Idmap::FromBinaryStream(idmap_static_no_name_raw_stream);
  ASSERT_TRUE(idmap_static_no_name);
  ASSERT_IDMAP(**idmap_static_no_name, GetTargetApkPath(), overlay_static_no_name_apk_path);

  auto idmap_static_1_raw_string = utils::ReadFile(idmap_static_1_path);
  auto idmap_static_1_raw_stream = std::istringstream(*idmap_static_1_raw_string);
  auto idmap_static_1 = Idmap::FromBinaryStream(idmap_static_1_raw_stream);
  ASSERT_TRUE(idmap_static_1);
  ASSERT_IDMAP(**idmap_static_1, GetTargetApkPath(), overlay_static_1_apk_path);

  auto idmap_static_2_raw_string = utils::ReadFile(idmap_static_2_path);
  auto idmap_static_2_raw_stream = std::istringstream(*idmap_static_2_raw_string);
  auto idmap_static_2 = Idmap::FromBinaryStream(idmap_static_2_raw_stream);
  ASSERT_TRUE(idmap_static_2);
  ASSERT_IDMAP(**idmap_static_2, GetTargetApkPath(), overlay_static_2_apk_path);

  unlink(idmap_static_no_name_path.c_str());
  unlink(idmap_static_2_path.c_str());
  unlink(idmap_static_1_path.c_str());

  // multiple input directories, non-recursive
  // clang-format off
  result = ExecuteBinary({"idmap2",
                          "scan",
                          "--input-directory", GetTestDataPath() + "/target",
                          "--input-directory", GetTestDataPath() + "/overlay",
                          "--target-package-name", "test.target",
                          "--target-apk-path", GetTargetApkPath(),
                          "--output-directory", GetTempDirPath(),
                          "--override-policy", "public"});
  // clang-format on
  ASSERT_THAT(result, NotNull());
  ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
  ASSERT_EQ(result->stdout, expected.str());
  unlink(idmap_static_no_name_path.c_str());
  unlink(idmap_static_2_path.c_str());
  unlink(idmap_static_1_path.c_str());

  // the same input directory given twice, but no duplicate entries
  // clang-format off
  result = ExecuteBinary({"idmap2",
                          "scan",
                          "--input-directory", GetTestDataPath(),
                          "--input-directory", GetTestDataPath(),
                          "--recursive",
                          "--target-package-name", "test.target",
                          "--target-apk-path", GetTargetApkPath(),
                          "--output-directory", GetTempDirPath(),
                          "--override-policy", "public"});
  // clang-format on
  ASSERT_THAT(result, NotNull());
  ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
  ASSERT_EQ(result->stdout, expected.str());
  unlink(idmap_static_no_name_path.c_str());
  unlink(idmap_static_2_path.c_str());
  unlink(idmap_static_1_path.c_str());

  // no APKs in input-directory: ok, but no output
  // clang-format off
  result = ExecuteBinary({"idmap2",
                          "scan",
                          "--input-directory", GetTempDirPath(),
                          "--target-package-name", "test.target",
                          "--target-apk-path", GetTargetApkPath(),
                          "--output-directory", GetTempDirPath(),
                          "--override-policy", "public"});
  // clang-format on
  ASSERT_THAT(result, NotNull());
  ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
  ASSERT_EQ(result->stdout, "");

  // the signature idmap failing to generate should not cause scanning to fail
  // clang-format off
  result = ExecuteBinary({"idmap2",
                          "scan",
                          "--input-directory", GetTestDataPath(),
                          "--recursive",
                          "--target-package-name", "test.target",
                          "--target-apk-path", GetTargetApkPath(),
                          "--output-directory", GetTempDirPath(),
                          "--override-policy", "public"});
  // clang-format on
  ASSERT_THAT(result, NotNull());
  ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
  ASSERT_EQ(result->stdout, expected.str());
  unlink(idmap_static_no_name_path.c_str());
  unlink(idmap_static_2_path.c_str());
  unlink(idmap_static_1_path.c_str());
}

TEST_F(Idmap2BinaryTests, Lookup) {
  SKIP_TEST_IF_CANT_EXEC_IDMAP2;

  // clang-format off
  auto result = ExecuteBinary({"idmap2",
                               "create",
                               "--target-apk-path", GetTargetApkPath(),
                               "--overlay-apk-path", GetOverlayApkPath(),
                               "--idmap-path", GetIdmapPath()});
  // clang-format on
  ASSERT_THAT(result, NotNull());
  ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;

  // clang-format off
  result = ExecuteBinary({"idmap2",
                          "lookup",
                          "--idmap-path", GetIdmapPath(),
                          "--config", "",
                          "--resid", R::target::string::literal::str1});
  // clang-format on
  ASSERT_THAT(result, NotNull());
  ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
  ASSERT_NE(result->stdout.find("overlay-1"), std::string::npos);
  ASSERT_EQ(result->stdout.find("overlay-1-sv"), std::string::npos);

  // clang-format off
  result = ExecuteBinary({"idmap2",
                          "lookup",
                          "--idmap-path", GetIdmapPath(),
                          "--config", "",
                          "--resid", "test.target:string/str1"});
  // clang-format on
  ASSERT_THAT(result, NotNull());
  ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
  ASSERT_NE(result->stdout.find("overlay-1"), std::string::npos);
  ASSERT_EQ(result->stdout.find("overlay-1-sv"), std::string::npos);

  // clang-format off
  result = ExecuteBinary({"idmap2",
                          "lookup",
                          "--idmap-path", GetIdmapPath(),
                          "--config", "sv",
                          "--resid", "test.target:string/str1"});
  // clang-format on
  ASSERT_THAT(result, NotNull());
  ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
  ASSERT_NE(result->stdout.find("overlay-1-sv"), std::string::npos);

  unlink(GetIdmapPath().c_str());
}

TEST_F(Idmap2BinaryTests, InvalidCommandLineOptions) {
  SKIP_TEST_IF_CANT_EXEC_IDMAP2;

  const std::string invalid_target_apk_path = GetTestDataPath() + "/DOES-NOT-EXIST";

  // missing mandatory options
  // clang-format off
  auto result = ExecuteBinary({"idmap2",
                               "create"});
  // clang-format on
  ASSERT_THAT(result, NotNull());
  ASSERT_NE(result->status, EXIT_SUCCESS);

  // missing argument to option
  // clang-format off
  result = ExecuteBinary({"idmap2",
                          "create",
                          "--target-apk-path", GetTargetApkPath(),
                          "--overlay-apk-path", GetOverlayApkPath(),
                          "--idmap-path"});
  // clang-format on
  ASSERT_THAT(result, NotNull());
  ASSERT_NE(result->status, EXIT_SUCCESS);

  // invalid target apk path
  // clang-format off
  result = ExecuteBinary({"idmap2",
                          "create",
                          "--target-apk-path", invalid_target_apk_path,
                          "--overlay-apk-path", GetOverlayApkPath(),
                          "--idmap-path", GetIdmapPath()});
  // clang-format on
  ASSERT_THAT(result, NotNull());
  ASSERT_NE(result->status, EXIT_SUCCESS);

  // unknown policy
  // clang-format off
  result = ExecuteBinary({"idmap2",
                          "create",
                          "--target-apk-path", GetTargetApkPath(),
                          "--overlay-apk-path", GetOverlayApkPath(),
                          "--idmap-path", GetIdmapPath(),
                          "--policy", "this-does-not-exist"});
  // clang-format on
  ASSERT_THAT(result, NotNull());
  ASSERT_NE(result->status, EXIT_SUCCESS);
}

}  // namespace android::idmap2
