/*
 * Copyright (C) 2017 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 <unistd.h>

#include <memory>
#include <string>
#include <vector>

#include <android-base/file.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <gtest/gtest.h>

#include "fuse_provider.h"
#include "fuse_sideload.h"

TEST(SideloadTest, fuse_device) {
  ASSERT_EQ(0, access("/dev/fuse", R_OK | W_OK));
}

TEST(SideloadTest, run_fuse_sideload_wrong_parameters) {
  auto provider_small_block =
      std::make_unique<FuseFileDataProvider>(android::base::unique_fd(), 4096, 4095);
  ASSERT_EQ(-1, run_fuse_sideload(std::move(provider_small_block)));

  auto provider_large_block =
      std::make_unique<FuseFileDataProvider>(android::base::unique_fd(), 4096, (1 << 22) + 1);
  ASSERT_EQ(-1, run_fuse_sideload(std::move(provider_large_block)));

  auto provider_too_many_blocks = std::make_unique<FuseFileDataProvider>(
      android::base::unique_fd(), ((1 << 18) + 1) * 4096, 4096);
  ASSERT_EQ(-1, run_fuse_sideload(std::move(provider_too_many_blocks)));
}

TEST(SideloadTest, run_fuse_sideload) {
  const std::vector<std::string> blocks = {
    std::string(2048, 'a') + std::string(2048, 'b'),
    std::string(2048, 'c') + std::string(2048, 'd'),
    std::string(2048, 'e') + std::string(2048, 'f'),
    std::string(2048, 'g') + std::string(2048, 'h'),
  };
  const std::string content = android::base::Join(blocks, "");
  ASSERT_EQ(16384U, content.size());

  TemporaryFile temp_file;
  ASSERT_TRUE(android::base::WriteStringToFile(content, temp_file.path));

  auto provider = std::make_unique<FuseFileDataProvider>(temp_file.path, 4096);
  ASSERT_TRUE(provider->Valid());
  TemporaryDir mount_point;
  pid_t pid = fork();
  if (pid == 0) {
    ASSERT_EQ(0, run_fuse_sideload(std::move(provider), mount_point.path));
    _exit(EXIT_SUCCESS);
  }

  std::string package = std::string(mount_point.path) + "/" + FUSE_SIDELOAD_HOST_FILENAME;
  int status;
  static constexpr int kSideloadInstallTimeout = 10;
  for (int i = 0; i < kSideloadInstallTimeout; ++i) {
    ASSERT_NE(-1, waitpid(pid, &status, WNOHANG));

    struct stat sb;
    if (stat(package.c_str(), &sb) == 0) {
      break;
    }

    if (errno == ENOENT && i < kSideloadInstallTimeout - 1) {
      sleep(1);
      continue;
    }
    FAIL() << "Timed out waiting for the fuse-provided package.";
  }

  std::string content_via_fuse;
  ASSERT_TRUE(android::base::ReadFileToString(package, &content_via_fuse));
  ASSERT_EQ(content, content_via_fuse);

  std::string exit_flag = std::string(mount_point.path) + "/" + FUSE_SIDELOAD_HOST_EXIT_FLAG;
  struct stat sb;
  ASSERT_EQ(0, stat(exit_flag.c_str(), &sb));

  waitpid(pid, &status, 0);
  ASSERT_EQ(0, WEXITSTATUS(status));
  ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
}
